티스토리 뷰





반응형

단항 부정, 단항 플러스

산술 연산자는 대부분 알고 있는데 단항 부정과 단항 플러스는 다소 생소할 것이다. 별거 아니지만 자바스크립트에서 사용될 수 있는 연산자다.

단항 부정
-x //x의 부호를 바꿀 수 있다. x가 5였다면 -5로 바꿔준다.

단항 플러스
+x //x가 숫자가 아니면 숫자로 변환을 시도한다. 
const s ="5";
const y = 3 + +s;
y => 8 //여기서 단항플러스가 없었다면 문자열병합을 시도하여 "35"가 되었을 것

비교연산자

=== 일치함, == 동등함

===은 같은 객체 or (같은 타입 and 같은 값)으로 이루어야 일치하게 나옵니다. 

== 동등함은 자료형과는 상관없이 값만 같으면 됩니다. 33 == "33"이 true가 나오기 때문에 여러가지 문제를 야기시킬 수 있습니다. 그렇기 때문에 괜히 동등연산자를 사용해서 불필요한 문제를 초래하지않길 권장합니다.

 

또한 객체 a와 b에 같은 정보가 들어 있더라도 그들은 서로 다른 객체이며, 일치하지도 않고 동등하지도 않습니다.

const a = {name:"object"}
const b = {name:"object"}

a === b //false
a == b //false

숫자비교 

숫자 비교할 때는 염두해야할 것이 있습니다. 먼저 특별한 숫자형 값 NaN은 그 자신을 포함하여 무엇과도 같지 않습니다. 즉, NaN === NaN과 NaN == NaN는 모두 false입니다. 숫자가 NaN인지 알아보려면 isNaN라는 내장함수를 이용해야 합니다. isNaN(x)는 x가 NaN일때 true이며 아니면 false입니다.

자바스크립트의 숫자는 모두 더블 형식 입니다. 그리고 더블 형식은 근사치이므로, 자바스크립트에서 숫자를 비교하다보면 경악스러운 결과를 볼 때가 있습니다. 

 

자바스크립트에서 정수를 비교할 때, 그 정수가 안전한 범위라면 안심하고 일치연산자를 사용할 수 있습니다. 하지만 소수점이 있는 숫자를 비교할 때는 관계 연산자를 써서 테스트하는 숫자가 대상 숫자에 충분히 가까운지 확인하는 편이 좋습니다. 바로 Number.EPSILON을 사용해서요. 이것은 매우 작은 값이며, 일반적으로 숫자 두개를 구별하는 기준으로 사용합니다.

let n = 0;
while(true){
	n +=0.1;
    if(n==0.3) break;
}
console.log("breaked!");

 위 소스를 실행하면 루프는 0.3에서 멈추지 않고 그 값을 살짝 피한다음 영원히 실행됩니다. 이 결과는 0.1이 더블 형식으로 정확히 나타낼 수 없는 값이기 때문입니다. 0.1은 이진 표현으로 나타낼 수 있는 숫자들 사이에 걸쳐 있습니다. 따라서 3번째 반복할 때 n의 값은 0.30000000000000004 이므로 테스트는 false라 유일한 종료 조건이 실패합니다.

let n = 0;
while(true){
	n +=0.1;
    if(Math.abs(n-0.3) < Number.EPSION) break;
}
console.log("breaked!!");

그냥 n이 0.3보다 큰지 확인하는 간단한 방법도 있지만, 여기서 사용한 방법은 두 개의 더블 형식이 같다고 할 수 있을 만큼 가까운 숫자인지 판단할 때 일반적으로 사용하는 방법입니다.

문자열 병합

자바스크립트에서 + 연산자는 덧셈과 문자열 병합에 모두 사용됩니다. 자바스크립트는 피연산자의 타입을 보고 덧셈을 할지 문자열 병합을 할지 판단합니다. 덧셈과 병합은 모두 왼쪽에서 오른쪽으로 평가합니다. 두 피연산자를 왼쪽에서 오른쪽으로 평가한 후, 피연산자 중 하나라도 문자열이면 문자열 병합을 수행합니다. 두 값이 모두 숫자형이면 덧셈합니다.

3 + 5 + "8"  //문자열 "88"
"3"+ 5 + 8 //문자열 "358"

참 같은 값과 거짓 같은 값

자바스크립트에서 거짓 같은 값은 다음과 같습니다.

  • undefined
  • null
  • false
  • 0
  • NaN
  • ""(빈 문자열)

이들 외에는 모두 참 같은 값입니다. 참 같은 값은 정말 많으므로 전부 나열할 수는 없지만 몇가지는 염두해야 합니다.

  • 모든 객체, valueOf( ) 메서드를 호출했을 때 false를 반환하는 객체도 참 같은 값에 속합니다.
  • 배열, 빈 배열도 참 같은 값에 속합니다.
  • 공백만 있는 문자열(" "등)
  • 문자열 "false"

혹시 빈 배열이 거짓 같은 값으로 평가되길 원한다면 arr.length를 사용하십시오. 빈 배열에서 이 프로퍼티를 호출하면 0을 반환하며 거짓 같은 값입니다.

단축 평가

x가 거짓같은 값이면 x && y는 y값을 평가할 필요도 없이 false입니다. 마찬가지로 x || y 에서 x의 값이 true라면 y의 값을 볼 필요도 없이 true가 반환됩니다. 자바스크립트는 정확히 이런 방식으로 동작하며, 이를 단축 평가라고 합니다.

const skipIt = true;
let x = 0;
const result = skipIt || x++

위와 같은 상황일 경우 result는 true 입니다. 그리고 x의 값은 여전히 0 입니다. 왜냐하면 단축 평가가 일어나므로 증가 연산자는 실행되지 않고 x의 값은 그대로 0이라는 겁니다. skipIt를 false한다면 그제서야 증가합니다.

const doIt = false;
let x = 0;
const result = doIt && x++

이번에도 두번째 평가가 이루어지지 않아 x의 값은 0 입니다. doIt을 true로 바꾸면 둘다 평가가 되고 result엔 0이 됩니다. 근데 잠깐, result가 true값이 아니라 0이 들어간다고요? 그 이유는 불리언 피연산자를 사용하면 논리 연산자는 항상 불리언을 반환합니다. 피연산자가 불리언이 아니라면, 결과를 결정한 값이 반환됩니다.

 

그래서 이러한 동작 방식을 활용한 아주 자주 쓰고, 또 보게될 표현이 있습니다.

const options = suppliedOptions || {name:"Default"};

객체(빈 값이여도)는 항상 참 같은 값으로 평가됩니다. 따라서 suppliedOptions가 객체이면 options는 suppliedOptions를 가리키게 됩니다. 옵션이 제공되지않으면, 즉 suppliedOptions가 null이나 undefined라면 options는 기본값을 갖게 됩니다.

쉼표 연산자

표현식을 결합하여 두 표현식을 평가한 후, 두 번째 표현식의 결과를 반환합니다. 표현식을 하나 이상 실행해야 하지만 값으로 필요한 것은 마지막 표현식의 결과뿐일 때 쉼표 연산자를 유용하게 쓸 수 있습니다.

let x = 0, y = 10, z;
z = (x++, y++);

z의 값은 10, 즉 y++가 반환하는 값입니다.

해체 할당

ES6에서 새로 도입한 해체 할당은 매우 환영받는 기능입니다. 이 기능은 객체나 배열을 변수로 해체할 수 있습니다. 객체 해체부터 시작합시다.

//객체 선언
const obj = {b:2, c:3, d:4};

//해체 할당
const {a,b,c} = obj;

a;		//undefined - obj에는 "a" 프로퍼티가 없다.
b;		//2
c;		//3
d;		//ReferrenceError - "d"는 정의되지않음

객체를 해체할 때는 반드시 변수 이름과 객체의 프로퍼티 이름이 일치해야 합니다. 프로퍼티 이름이 유효한 식별자인 프로퍼티만 해체 후 할당이 됩니다.

이 예제는 선언과 할당을 같은 문에서 실행했습니다. 객체 해체는 할당만으로 이뤄질 수도 있지만, 그렇게 하려면 반드시 괄호가 필요합니다. 괄호를 쓰지 않으면 자바스크립트는 표현식 좌변을 블록으로 해석합니다.

const obj = {b:2, c:3, d:4};
let a,b,c;

//에러가 일어납니다.
{a,b,c} = obj;

//동작합니다.
({a,b,c} = obj);

배열을 해체할 때는 배열 요소에 대응하는 변수 이름을 맘대로 정할수 있으며 배열 순서대로 대응합니다.

const arr = [1,2,3];

//배열 해체 할당
let [x,y] = arr;

x;		//1
y;		//2

이렇게 하면 3 이라는 데이터는 버려지지만 확산 연산자(...)을 사용하면 남은 요소를 새 배열에 할당할 수 있다.

const arr = [1,2,3,4,5];

//배열 해체 할당
let [x,y, ...rest] = arr;

x;		//1
y;		//2
rest;   //[3,4,5]
let a=5, b=10;
[a,b] = [b,a]
a;		//10
b;		//5

 

반응형
댓글
반응형
최근에 달린 댓글
글 보관함
Total
Today
Yesterday
최근에 올라온 글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31