[javascript] operator
- 참고 사이트
- 연산자
- 산술 연산자
- 할당 연산자
=
- 비교연산자
- 논리 연산자
- 비트 연산자
- 삼항 연산자
? :
- 쉼표 연산자
- 단항연산자
- 관계 연산자
- Null 병합 연산자, Nullish coalescing operator
??
- 버림 연산자
~~
참고 사이트
표현식과 연산자
operators
comparison
logical-operators
연산자
-
산술 연산자
+ - * / % ++ --
-
할당 연산자
= += -= *= /= %= &= ^= |= <<= >>= >>>=
-
비교 연산자
== === != !== > < >= <=
-
논리 연산자
&& || !
-
비트연산자
~ & | ^ << >> >>>
이항연산자
피연산자 y, z
2개를 받는 연산자를 이항연산자라고 한다. 보통 수학에서 배우는 사칙연산자와 같다.
let y = 10, z = 39;
alert( z - y ); // 29
산술 연산자
나머지 연산자 %
/
는 몫을 리턴하지만 %
는 나머지를 리턴한다.
alert( 10 % 3 ); // 1 -> 10/3은 몫 3, 나머지 1인데 %는 나머지를 리턴한다.
거듭제곱 연산자, 지수화 연산자 **
alert( 2 ** 10); // 1024 -> 2*2*2*2*2*2*2*2*2*2
alert( 4 ** (1/2)); // 2 -> 4는 2의 제곱근
alert( 8 ** (1/3)); // 2 -> 8은 2의 세제곱근
이항연산자 +
와 문자열 연결
수학에서는 숫자만 더하지만 자바스크립트에서는 문자열끼리의 결합도 +
로 할 수 있다.
- 문자열 + 문자열 = 문자열
- 문자열 + 숫자 = 문자열
- 숫자 + 문자열 = 문자열
문자열이 섞이면 무조건 문자열로 리턴된다.
let s = "my" + "javascript";
alert(s); // myjavascript
alert( '3' + 9 ); // 39
alert( 3 + '9' ); // 39
alert( 2 + 1 + '9') // 39 -> 왼쪽부터 순차적으로 진행되므로 2+1 = 3 후에 30 + '9'
- 그에 비해 다른 사칙연산자들은 인수를 모두 숫자형으로 변환시켜 계산을 한다.
alert('10' - 2); // 8
alert('10' / '2'); // 5
단항연산자 +
와 숫자형으로 변환
+
+ 숫자 = 그대로 숫자
+
+ 그 외 = 숫자로 변환
let x = 1;
alert(+x); // 1
let y = -2;
alert(+y); // -2
alert(+true); // 1 -> Number(true)와 같은 결과
alert(+''); // 0 -> Number('')와 같은 결과
- 이항연산자
+
let first = '3'; let last = '9'; alert(first + last); // 39 -> 이항연산자 +는 문자열 연결
- 단항 & 이항연산자
+
first = '30'; last = '9'; alert(+first + +last); // 30 + 9 = 39
연산자 우선순위
우선순위 테이블의 순위의 숫자가 클수록 우선순위가 높으나 ()
괄호는 최우선이다. 단항덧셈이 이항덧셈보다 우선순위가 높기때문에 먼저 수행된다. 순위가 같은 경우에는 왼쪽에서 오른쪽으로 수행된다.
순위 | 연산자이름 | 기호 |
---|---|---|
15 | 단항덧셈 | + |
12 | (이항)덧셈 | + |
- 우선순위 표 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
Precedence | Operator type | Associativity | Individual operators |
---|---|---|---|
19 | Grouping | n/a | ( … ) |
18 | Member Access | left-to-right | … . … |
Computed Member Access | left-to-right | … [ … ] | |
new (with argument list) | n/a | new … ( … ) | |
Function Call | left-to-right | … ( … ) | |
Optional chaining | left-to-right | ?. | |
17 | new (without argument list) | right-to-left | new … |
16 | Postfix Increment | n/a | … ++ |
Postfix Decrement | … – | ||
15 | Logical NOT | right-to-left | ! … |
Bitwise NOT | ~ … | ||
Unary Plus | + … | ||
Unary Negation | - … | ||
Prefix Increment | ++ … | ||
Prefix Decrement | – … | ||
typeof | typeof … | ||
void | void … | ||
delete | delete … | ||
await | await … | ||
14 | Exponentiation | right-to-left | … ** … |
13 | Multiplication | left-to-right | … * … |
Division | … / … | ||
Remainder | … % … | ||
12 | Addition | left-to-right | … + … |
Subtraction | … - … | ||
11 | Bitwise Left Shift | left-to-right | … « … |
Bitwise Right Shift | … » … | ||
Bitwise Unsigned Right Shift | … »> … | ||
10 | Less Than | left-to-right | … < … |
Less Than Or Equal | … <= … | ||
Greater Than | … > … | ||
Greater Than Or Equal | … >= … | ||
in | … in … | ||
instanceof | … instanceof … | ||
9 | Equality | left-to-right | … == … |
Inequality | … != … | ||
Strict Equality | … === … | ||
Strict Inequality | … !== … | ||
8 | Bitwise AND | left-to-right | … & … |
7 | Bitwise XOR | left-to-right | … ^ … |
6 | Bitwise OR | left-to-right | … | … |
5 | Logical AND | left-to-right | … && … |
4 | Logical OR | left-to-right | … || … |
Nullish coalescing operator | left-to-right | … ?? … | |
3 | Conditional | right-to-left | … ? … : … |
2 | Assignment | right-to-left | … = … |
… += … | |||
… -= … | |||
… **= … | |||
… *= … | |||
… /= … | |||
… %= … | |||
… «= … | |||
… »= … | |||
… »>= … | |||
… &= … | |||
… ^= … | |||
… |= … | |||
yield | right-to-left | yield … | |
yield* | yield* … | ||
1 | Comma / Sequence | left-to-right | … , … |
할당 연산자 =
우선순위가 낮은 편이다.
let a = 20 * 2 - 1 // 1) `*` 2) `-` 3) `=`
alert(x); // 39
값을 리턴하는 할당 연산자
아래와 같이 =
의 할당 속성을 이용해서 수행이 가능하지만 가독성도 좋지 않도 명확성이 떨어지므로 비추.
let a = 1;
let b = 2;
let c = 3 - ( a = b + 1); // 1) b+1, 2) a = b + 1, 3) 3 - (a = b + 1), 4) c = 3 - (a = b + 1)
alert(a); // 3
alert(c); // 0
할당 연산자 체이닝
let a, b, c;
a = b = c = 2 + 2; // 1) 2+2, 2) c=2+2, 3) b=c, 4) a=b
alert(a);// 4
alert(b);// 4
alert(c);// 4
아래가 더 가독성이 좋음
c = 2 + 2;
b = c;
a = b;
복합 할당 연산자
let n = 15;
n *= 2; // 15 * 2 = 30를 한 후 n에 할당 -> n = n * 2
n += 9; // 30 + 9 = 39를 한 후 n에 할당 -> n = n + 9
alert(n); // 39
복합 할당 연산자의 우선순위는 할당연산자의 순위와 같이 낮다.
let n = 2;
n *= 3 + 5;
alert (n); // 2 * ( 3 + 5) = 16 -> n *= 8이 먼저
증가/감소 연산자 ++
, --
let counter = 2;
counter++; // counter = counter + 1;
alert(counter); // 3
counter = 2;
counter--; // counter = counter - 1;
alert(counter); // 1
5++; // SyntaxError: invalid increment/decrement operand -> 변수에만 쓸수 있음
- 후위형, 전위형
+1 혹은 -1로 증가/감소처리는 후위형이든 전위형이든 동일하게 처리한다.
후위형:counter++;
- 변수에 값이 할당이 되면 증가/감소 전의 기존 값을 리턴
전위형:++counter;
- 변수에 값이 할당이 되면 증가/감소 후의 새로운 값을 리턴
let counter = 1;
let a = ++counter;
alert(a); // 2
counter = 1;
let b = counter++;
alert(b); // 1
counter = 0;
counter++; // counter = 1
++counter; // counter = 2
alert(counter); // 2
비교연산자
<
, >
, <=
, >=
, ==
, !=
boolean
형을 리턴
문자열 비교
유니코드값에 따라 크고 작음을 판단. 일반적인 사전순으로 문자열을 비교하는 것과 같으나 자바스크립트는 대소문자도 구분하여 비교.
소문자가 더 값이 큼.
alert('Z' > 'z'); // false
다른 형끼리 비교
사칙연산자와 마찬가지로 비교연산자 역시 인수를 숫자형으로 자동변환하여 비교한다.
alert('39' < 40 ); // true
alert(true == 1); // true
let a = 0;
alert( Boolean(a)); // boolean 0은 false
let b = '0';
alert(Boolean(b)); // 문자열의 boolean타입은 true
alert(a == b); // 비교연산자는 모든 인수를 숫자형으로 변환하므로 0=0으로 true
동등 연산 ==
의 판단 기준
같은 타입, 같은 값을 가지고 있는 두 값은 동등 문자열과 숫자 비교 시 타입은 문자열은 숫자로 변환되고 그 값이 같으면 동등.
1 == 1; // true
1 == '1'; // true
두 값 중 하나가 null
이고 다른 하나가 undefined
라면 두 값은 동등
null == undefined; // true
null
은 동등비교시 다른 비교연산과는 달리 숫자로 변환되지 않는다. 따라서
null
과 undefined
자체 동등 비교 결과는 참이지만 다른 모든 값들과 비교하면 모두 false
결과를 얻게 된다.
null == 0; // false
undefined
는 비교연산 시 NaN
로 변환되고, 동등비교에서는 다른 어떤 값과도 같지 않기 때문에 모두 false
다.
undefined == 0; // false
boolean
값과 비교시 true
는 1로 변환, false
는 0으로 변환 후 비교
true == '1'; // true : 1 == '1' 비교로 변환된다.
true == '2'; // false
객체와 숫자 혹은 문자열 비교이면, 객체를 원시 타입으로 변환 후 비교
[2] == '2'; //true
일치 연산자 ===
동등 연산자 ==
는 자동형변환으로 0과 false
를 구별하지 못하지만 일치 연산자 ===
는 형까지 비교를 하므로 구별할 수 있다.
alert(0 === false); // false, 피연산자의 형이 다름
1 === '1'; // false
두 값 중 하나가 null
이고 다른 하나가 undefined
라면 두 값은 불일치
null === undefined; // false
NaN
값은 자신을 포함해 다른 어떤 값과도 일치하지 않음
NaN === NaN; // false
0은 -0은 일치
0 === -0; // true
모두 같은 객체나 배열 또는 함수를 참조하고 있다면 두 값은 일치하지만,
같은 프로토타입에 의해 생성된 2개의 객체는 일치하지 않는다.
function Fn(){ console.log(1) }
var a = Fn;
var a1 = Fn;
a === a1; // true
var b = new Fn();
var c = new Fn();
b === c; // false
({a:1}) === ({a:1}); // false
null과 undefined 비교
일치 연산자 ===
를 제외하고 비교연산자는 null
이나 undefined
이 피연산자로 올 경우 원하지 않는 결과가 나올수 있으므로
주의해야한다. 따라서 변수가 null
이나 undefined
가 될 가능성이 있다고 판단되면 따로 처리하는 코드가 필요하다.
alert(null === undefined); // false, 형이 다름
alert(null == undefined); // true, 예외 규칙임
alert(null < undefined); // false, null은 0, undefined는 NaN
null
vs 0
alert(null > 0); // false, 0 > 0 이므로
alert(null == 0); // false, 동등연산자는 null이나 undefined는 형변환하지 않으므로 비교 불가
alert(null >= 0); // true, 0 >= 0 -> 실제 이런 결과를 원하지 않을수도 있으므로 주의해야함.
- 비교 불가능한
undefined
alert(undefined > 0); // false, NaN > 0
alert(undefined < 0); // false, NaN < 0
alert(undefined == 0); // false, 동등연산자는 null이나 undefined는 형변환하지 않으므로 비교 불가
논리 연산자
피연산자가 boolean
이 아닐 때 피연산자를 boolean
으로 변환하여 비교하며,
리턴시엔 변환되기 전의 원래 값을 리턴한다.
undefined && 1; // false && true로 변환 후 비교, undefined 리턴
true && '123'; // true && true로 변환 후 비교, '123' 리턴
다른 연산자처럼 피연산자를 평가(evaluate)
하는 과정을 거치는데,
함수의 경우 실행 후 리턴된 값을 boolean
으로 변환하여 판단한다.
따라서 연산자에 따라 함수가 둘 다 실행될 수도 있고 좌변의 함수만 실행될 수도 있다.
alert(1) && alert(2); // alert(1)만 실행
alert(1) || alert(2); // 둘 다 실행
AND 연산 &&
좌변, 우변 모두 true
여야 하는데, 좌변이 false
일 때는 우변을 검사할 필요 없어 좌변 값을 리턴한다. 즉, false
를 만나면 검사 종료
undefined && 1; // false && 1로 변환하여 검사하지만 좌변이 false이므로 좌변의 값인 undefined가 리턴
좌변이 true
일 때는 우변도 검사하여 true, false
결과에 상관없이 우변 값을 리턴
true && 1; // true && true -> 우변 값인 1 리턴
true && undefined; // true && false -> 우변 값인 undefined 리턴
논리연산자의 조건 중 복잡한 것은 가장 마지막에 체크하도록 코딩하는 것이 좋다.
v1
이 false
라면 바로 false
를 리턴하므로 불필요하게 복잡한 fn()
을 체크할 필요가 없다.
const v1 = '';
const v2 = true;
console.log(`&&연산자: ${v1 && v2 && fn()}`); // 아래보다 더 좋은 예시
console.log(`&&연산자: ${fn() && v1 && v2}`);
OR 연산 ||
좌변, 우변 중 하나만 true
이면 되므로, 좌변이 true
일 때는 우변을 검사할 필요 없이 좌변 값을 리턴한다. 당연히 true
가 없을때는 끝까지 검사 후 마지막 값을 리턴한다.
1 || false; // true || false -> 좌변 값인 1 리턴
좌변이 false
일 때는 우변도 검사하여 true, false
결과에 상관없이 우변 값을 리턴
0 || null; // false || false -> 우변 값인 null 리턴
alert()
은 undefined
가 리턴된다.
alert( alert(1) || 2 || alert(3) );
/*
alert()은 boolean값을 리턴하지 않고 undefined가 리턴되므로 alert(1)를 검사한 후 false로 판단,
다음 값을 검사하고 2는 true이므로 2 그대로 리턴, 그것이 바깥 alert()의 값으로 들어가게 되어 결국 알럿 1, 2가 리턴된다.
*/
&&
와 ||
로 만드는 삼항 연산자
var a = 1;
var b = 2;
var resulta = (a == 1) && 'equal' || 'not equal';
var resultb = (b == 1) && 'equal' || 'not equal';
/*
(a == 1) && 'equal' || 'not equal'
true && 'equal' || 'not equal' -> && 연산의 좌변이 true이므로 우변 검사
'equal' || 'not equal'
true || true -> 문자열은 true이고 || 연산의 좌변이 true이므로 좌변 값 리턴
'equal'
(b == 1) && 'equal' || 'not equal'
false && 'equal' || 'not equal' -> && 연산의 좌변이 false이므로 좌변 리턴
(b == 1) || 'not equal'
false || 'not equal' -> ||연산의 좌변이 false이므로 우변 값 리턴
'not equal'
*/
&&
와 ||
연산자로 null 체크
다음과 같이 객체에 접근하기 전에 null
객체인지, 아닌지를 검사하는데 유용하게 사용될 수 있다.
var name = o && o.getName();
// o 객체가 null이면 오류
var name = otherName || "default";
// otherName이 null이면 default 문자열을 name을 부여
NOT 연산자 !
boolean
값을 반대 값으로 변환한다. &&
나 ||
보다 우선순위가 높다.
alert( !true ); // false
alert( !0 ); // true
!!
형태로도 쓰이기도 하는데 이건 반대값을 다시 반대로 반환하기 때문에 결국 원래 boolean
평가값과 같고 Boolean()
함수를 실행한것과 같다.
alert( !!"non-empty string" ); // true
alert( !!null ); // false
alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false
비트 연산자
비트 연사자는 인수를 32비트 정수로 변환하여 이진 연산을 수행
일반적인 개발에서 쓰일일은 거의 없지만 암호를 다뤄야 할때는 유용.
바이너리 연산으로 산술연산보다 속도가 빠르다.
&
(비트 AND)|
(비트 OR)^
(비트 XOR)~
(비트 NOT)<<
(왼쪽 시프트)>>
(오른쪽 시프트)>>>
(부호 없는 오른쪽 시프트)
비트 단위 NOT 연산자 ~
피연산자의 32비트가 모두 뒤집힌다. (1은 0으로, 0은 1로)
이 과정에서 가장 왼쪽의 부호 비트도 뒤집히면서 양수는 음수로, 음수는 양수로 바뀐다.
~10; // -11
~-10; // 9
비트 단위 AND 연산자 &
10진수 10 = 2진수 1010
10진수 11 = 2진수 1011
둘을 AND
연산한 결과는 1010
10 & 11; // 10
/* 실제론 아래와 같이 2진수로 연산
1010
1011
----
1010 -> 1 & 1 = 1로 리턴 그 외는 모두 0
*/
비트 단위 OR 연산자 |
10진수 10 = 2진수 1010
10진수 11 = 2진수 1011
둘을 OR
연산하여 결과는 1011
10 | 11; // 11
/* 실제론 아래와 같이 2진수로 연산
1010
1011
----
1011 -> 0 | 0 = 0 그 외에는 모두 1
*/
비트단위 XOR 연산자 ^
10진수 10은 2진수 1010
10진수 11은 2진수 1011
XOR
결과 0001
10 ^ 11; // 1
/* 실제론 아래와 같이 2진수로 연산
1010
1011
----
0001 -> 같은 숫자는 0, 다른 숫자일경우는 1
*/
좌측 시프트 연산자 <<
<<
는 우변의 숫자 n만큼 2의 n제곱을 해 준다.
10 << 1; // 20 -> 10 * (2의 1제곱)
10 << 3; // 80 -> 10 * (2의 3제곱)
2 << 2; // 8 -> 2 * (2의 2제곱)
역시 실제론 2진수로 연산이 된다.
10진수 10은 2진수 1010으로 아래와 같은 형태라고 보면
|0|0|0|0|…|1|0|1|0| |-|-|-|-|—|-|-|-|-|
이걸 좌측으로 한 칸 시프트 하면(10 << 1
) 10100이 된다. (새로 추가된 자리는 0으로 채움)
|0|0|0|0|…|1|0|1|0|0
|
|-|-|-|-|—|-|-|-|-|—|
2진수 10100값은 10진수로 16 + 4 = 20
이 된다.
2진수 | 1 | 0 | 1 | 0 | 0 |
---|---|---|---|---|---|
10진수(2^n) | 16 | 8 | 4 | 2 | 1 |
같은 방식으로 10 << 3
은 좌측으로 3칸 시프트 하면 1010000이 되고
2진수 1010000값은 10진수로 64 + 16 = 80
이 된다.
2진수 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
---|---|---|---|---|---|---|---|
10진수(2^n) | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
우측 시프트 연산자 >>
>>
는 우변의 숫자 n
만큼 2의 n
제곱을 나누어 준다.
10 >> 1; // 5 -> 10 / (2의 1제곱)
10 >> 3; // 1 -> 10 / (2의 3제곱)
역시 실제론 2진수로 연산이 된다.
10진수 10은 2진수 1010으로 아래와 같은 형태라고 보면
|0|0|0|0|…|1|0|1|0| |-|-|-|-|—|-|-|-|-|
이걸 우측으로 한 칸 시프트 하면(10 >> 1
) 101이 된다. (마지막 자리는 삭제된다.)
|0|0|0|0|…|1|0|1| |-|-|-|-|—|-|-|-|
2진수 101값은 10진수로 4 + 1 = 5
이 된다.
2진수 | 1 | 0 | 1 |
---|---|---|---|
10진수(2^n) | 4 | 2 | 1 |
같은 방식으로 10 >> 3
은 우측으로 3칸 시프트 하면 0001이 된다. (마지막 3자리는 삭제된다.)
|0|0|0|0|…|1| |-|-|-|-|—|-|
2진수 0001값은 10진수로 1
이 된다.
2진수 | 1 |
---|---|
10진수(2^n) | 1 |
단, 음수의 경우 맨 좌측의 부호비트는 유지된다.
그래서 -10(1000000000…1010)을 우측으로 한 번 시프트 하면
|1|0|0|0|…|1|0|1|0| |-|-|-|-|—|-|-|-|-|
-5(1000000000…101)가 된다.
|1
|0|0|0|…|1|0|1|
|—|-|-|-|—|-|-|-|
unsigned 우측 시프트 연산자 >>>
양수의 경우 >>
와 같다. 음수의 경우만 >>
와 다른데, 부호 비트를 무시하고 전체를 시프트하기 때문에
가령 -10(1000000000…1010)을 우측으로 한 번 시프트하면 2147483643(0100000000…101)가 된다.
10 >>> 1; // 5 -> `>>` 와 같은 결과
-10 >>> 1; // 2147483643 -> 2진수로 변환되어 계산 후 다시 10진수로
삼항 연산자 ? :
조건 연산자 또는 선택 연산자. TRUE
혹은 FALSE
에 해당하는 값을 리턴한다.
조건식 ? 조건이 참일때 표현식 혹은 값 : 조건이 거짓일때 표현식 혹은 값
let i = 1;
let rs = (i = 0) ? '값 없음' : '값 있음'; // 값
console.log(rs);
(i = 0) ? alert('값 없음') : alert('값 있음'); // 표현식
삼항연산자는 표현식과 값을 사용할 수 있지만 break
나 continue
같은 문법구문과는 함께 사용 할 수 없다.
(i = 0) ? alert(i) : continue; // SyntaxError: Unexpected token 'continue'
// 아래와 같이 사용은 가능
if (i = 0) {
alert(i);
} else {
continue;
}
쉼표 연산자
거의 쓰이지 않으나 코드를 짧게 쓰일 목적으로 가끔 사용
, 가 포함되어 있는 모든 표현식은 평가는 되지만 마지막 표현식의 결과만 리턴
let a = (1 + 2, 3 + 4);
alert(a); // `()` 안이 먼저 연산, 그 안의 1+2=3, 3+4=7 표현식중 마지막 3+4=7만 리턴, 3은 무시
a = 1 + 2, 3 + 4
alert(a); // a = 3, 7로 `+`가 먼저 연산되어 a = 3, 7, `,`보다 `=`의 우선순위가 높아 a=3 리턴되고 7은 무시
for(a = 1, b = 3, c = a * b; a < 10; a++){
// c = a * b만 리턴?
}
단항연산자
피연산자 x
하나만 받는 연산자는 단항연산자라고 한다.
피연산자(operand)
는 인수(argument)
라고도 한다.
let x = 5;
x = -x;
alert(x); // -5
delete
객체의 프로퍼티를 삭제하는 연산자.
var fn = { word: "hi" };
console.log(fn.word); // "hi"
delete fn.word; // true
console.log(fn.word); // undefined
객체의 프로퍼티만 삭제가 가능하므로, var
키워드로 정의된 변수나 함수 선언문으로 정의된 함수, 함수 매개변수는 삭제할 수 없다.
var aaa;
delete aaa; // false
function fn(a) {
console.log(delete a); // false
}
console.log(delete fn); // false
typeof
연산자 다음에오는 변수, 함수, 객체 또는 표현식의 타입을 리턴한다.
typeof "John" // "string"
typeof 3.14 // "number"
typeof NaN // "number"
typeof false // "boolean"
typeof [ 1, 2, 3, 4 ] // "object"
typeof { name: 'John', age: 34 } // "object"
typeof new Date() // "object"
typeof function() {} // "function"
typeof myCar // "undefined" (if myCar is not declared)
typeof null // "object"
void
피연산자를 실행하되 무조건 undefined
를 리턴하는 연산자.
function bbb() {
return 'hello world!';
}
console.log(bbb()); // 'hello world!'
console.log(void bbb()); // undefined
같은 이름의 void(any)
함수는 매개변수로 아무 값이나 받아도 상관없는 항상 undefined
를 리턴하는 함수다.
관계 연산자
in
객체나 배열의 특정 프로퍼티가 존재하는지 확인하고 있을 경우 true
를 리턴하는 연산자
var obj = {
a: 1,
b: 2
};
'a' in obj; // true
for-in 반복문에서 사용하기도 한다.
for (var ele in obj) {
console.log(ele); // 'a', 'b'
console.log(obj[ele]); // 1, 2
}
단, 이 경우 해당 객체의 프로퍼티 중 객체가 소유한 프로퍼티(own properties)
만 가져온다.
즉, 프로포타입으로부터 상속받은 프로퍼티는 무시한다.
obj.toString; // ƒ toString() { [native code] } - 프로토타입으로 부터 받은 프로퍼티로 존재
obj.toString in obj; // false
instanceof
좌측의 객체가 우측의 생성자 함수로 만들어진건지 확인하는 연산자
var obj = {};
obj instanceof Object; // true
function Newbie() {}
var noob = new Newbie();
noob instanceof Newbie; // true
Null 병합 연산자, Nullish coalescing operator ??
피연산자 중 null
이나 undefined
가 아닌 값을 리턴한다. 즉, 검사 중 결과값이 정의된 값을 찾아 리턴한다.
let user;
alert(user ?? "Anonymous"); // Anonymous - user는 정의되지 않았으므로 정의여부를 확인할때 써도 유용할듯
||
연산자와 쓰임이 비슷해 보이나 ||
연산자는 false, 0, null, undefined, ''
를 모두 falsy
로 취급하므로 각각의 구분을 할 수가 없다.
즉, null/undefined
만 걸러내고 싶은 경우 ??
연산자를 사용할 수 있다.
let height = 0;
alert(height || 100); // 0 || 100의 비교로 0은 falsy이므로 truthly인 100을 리턴
alert(height ?? 100); // height는 0으로 정의가 되어 있으므로 리턴
연산 우선순위는 낮은 편으로 필요하면 ()
로 묶어 우선순위를 높여야 한다. 최근에 추가된 연산자로 제공되지 않는 브라우저가 있을 수 있고 &&
나 ||
연산자와 혼용해서 쓸 때는 ()
로 우선순위를 지정해 주어야 한다.
연습문제
'' + 1 + 0 // 1 -> 10 --> ''이 `+` 로 엮일때는 문자열로 인식
'' - 1 + 0 // -1 --> `-`는 숫자만 받으므로 ''를 0으로 인식
true + false // 1
6 / '3' // 2
'2' * '3' // 6
4 + 5 + 'px' // 9px
'$' + 4 + 5 // $45
'4' - 2 // 2
'4px' - 2 // 4px2 -> NaN --> `-`는 숫자만 받는데 '4px'는 숫자로 변환불가
7/0 // infinity
' -9 ' + 5 //-4 -> ' -9 5' --> `+`는 문자열을 그대로 받는다
' -9 ' - 5 // -14 ** `-`는 숫자만 인수로 받기때문에 형변환한다.
null + 1 // 1
undefined + 1 // NaN
' \t \n' - 2 // NaN -> -2 --> `\t\n` 은 공백을 뜻한다.
- 결과가 12가 아닌 3이 되도록 수정하라
let a = prompt('First number?', 1);
let b = prompt('Second number?', 2);
// alert(a + b); // 12
alert(+a + +b); // 3
버림 연산자 ~~
let v = Math.floor(3.14); // 3
let o = ~~3.14; // 3