이 기록은 inflearn의 자바스크립트 비기너: 튼튼한 기본 만들기의 강좌를 들으면서 보충자료와 함께 제 나름대로의 문장으로 재구성한 내용입니다.
연산의 사전적 의미는 규칙에 따라 계산하여 값을 구함이다. javascript에서 말하는 연산자의 연산도 사전적 의미와 같을까? 이는, javascript에서 활용하는 연산자의 예시를 보면 쉽게 알 수 있다.
# 다양한 연산자의 형태
- +,-,*,/,%
- >,>=,<,<=
- ==,!=,===,!==
- 콤마(,),typeof,delete,void
- instanceof,in,new 등
+
를 예시로 살펴보면, 규칙(+ left-side에 값, +right-side에 값을 두고), 계산(left-side와 right-side를 더하여), 값을 구한다. typeof
연산자도 마찬가지로, 규칙(typeof right-side에 변수를 두고), 계산(right-side 변수의 타입을 구하고), 값(변수의 타입)을 구한다. 따라서, 연산의 사전적 의미는 javascript
에서 사용하는 연산자의 "연산"과 동일하다.❗ javascript의 연산자는 내가 알고 있는(?) 연산을 한다❗
❗ +,- 외에도 여러가지 연산자가 존재한다(typeof, new 등등)❗
표현식은 값으로 이행하는 임의의 유효한 코드 단위(An expression is any valid unit of code that resolves to a value.)
1+2 //1도 표현식,2도 표현식, 1+2도 표현식
const total = 1+2; //할당도 표현식
const value = total/(2+3); // 괄호안에 있는 (2+3)도 표현식,나누는것도 표현식, 할당도 표현식
typeof value; //이것도 표현식
1+2
와 같이 계산을 하는 행위를 "표현식을 평가" 한다고 하며, 표현식을 평가하면 결과과 반환되는데 이를 "평가 결과"라고 한다.
(1
자체도 표현식 및 표현결과, 2
자체도 표현식 및 표현결과, 1+2
는 두 표현 결과를 더하는 표현식)
=
하나만 사용+=
,-=
,*=
,/=
,%=
<<=
,>>=
<<<=
,&=
,%=
,|=
=
앞을 연산한 후, 할당 let value = 3;
value+=2; //var+2를 연산한 후, 할당, var=var+2;와 같은 해석
console.log(value); //5
+
양쪽의 표현식을 평가 ( 각 평가결과를 더함)const two = "2";
const value = 1+3+two ; // 42, 한쪽이라도 평가결과가 Number타입이 아니면 평가결과를 더하지 않고 연결
console.log(typeof value); // string
값 타입 | 변환 값 |
---|---|
undefined | NaN |
Null | 0 |
Boolean | true :1, false :0 |
Number | 변환 전/후 같음 |
String | 값이 숫자이면 숫자로 연산(단, + 는 연결) |
let value;
console.log(10+value); //Nan(10+NaN)
console.log(10+null); //10(10+0)
console.log(10+true); //11(10+1)
console.log(123-"23"); //100(123-23)
console.log(10+"123"); //"10123" (+연산자는 한쪽이라도 Number아닐 경우, 연결)
-
연산자 : 왼쪽 표현식 평가 결과에서 오른쪽 표현식 평가 결과 뺌, Number
타입으로 변환하여 계산(+
와는 다름)// String 타입이지만, 값이 숫자이면 `Number` 타입으로 변환하여 계산
console.log(123-"23") //100
console.log(123-null) //123
console.log(123-true) //122
console.log(123-undefined) //NaN
console.log(123-"AB") //NaN
*
연산자 : 왼쪽 표현식 평가 결과에서 오른쪽 표현식 평가 결과를 곱함, Number
타입으로 변환하여 계산(+
와는 다름)// String 타입이지만, 값이 숫자이면 `Number` 타입으로 변환하여 계산
console.log(123*"2") //246
console.log(123*null) //0
console.log(123*true) //123
console.log(123*undefined) //NaN
console.log(123*"AB") //NaN
// IEEE754 유동소수점 이슈 및 대응방법
console.log(2.3*3) //6.89999999999999995(6.9로 출력되지 않음)
console.log(((2.3*10)*3)/10) // 대응방법: 실수를 정수로 변환하여 값을 구하고, 당시 절수를 실수로 변환
/
연산자 : 왼쪽 표현식 평가 결과에서 오른쪽 표현식 평가 결과를 나눔Number
타입으로 변환하여 계산(+
와는 다름)// String 타입이지만, 값이 숫자이면 `Number` 타입으로 변환하여 계산
console.log(124/"2") //62
console.log(123/null) //Infinity
console.log(123/true) //123
console.log(123/undefined) //NaN
console.log(123/"AB") //NaN
%
연산자 : 왼쪽 표현식 평가 결과를 오른쪽 표현식 평가 결과로 나누어 나머지를 구함Number
타입으로 변환하여 계산(+
와는 다름)// String 타입이지만, 값이 숫자이면 `Number` 타입으로 변환하여 계산
console.log(123%"2") //1
console.log(123%null) //NaN
console.log(123%true) //0
console.log(123%undefined) //NaN
console.log(123%"AB") //NaN
// IEEE754 유동소수점 이슈 및 대응방법
console.log(5%2.5) //0
console.log(5%2.3) //0.40000000000000036(0.4가 나오지않음)
console.log((5*10)%(2.3*10)/10) // 대응방법: 실수를 정수로 변환하여 값을 구하고, 당시 절수를 실수로 변환
Number()
와 기능같음), 연산시에만 바꿈(원래 값은 바뀌지 않음)Number()
를 추천let value = "7"
console.log(typeof value) //String
console.log(typeof +value) //Number
console.log(typeof Number(value)) //Number
console.log(typeof value) //String
let value = "7"
console.log(-value) //-7
console.log(8 + -value) //1
console.log(value) //"7"
let one1 = 1, one2 = 1;
let value1 = one1++ +3; // 1+3
console.log(value1); //4
console.log(one1); //2
let value2 = one2-- +3; // 1+3
console.log(value2); //4
console.log(one2); //0
let one1 = 1, one2 = 1;
let value1 = ++one1 +3; // 2+3
console.log(value1); //5
console.log(one1); //2
let value2 = --one2 +3; // 0+3
console.log(value2); //3
console.log(one2); //0
❓
let one = 1; console.log(one++ + ++one);
는 무엇일지 생각해보자. (내 예상답안 :3 이었는데 뭐가 잘못됐지?)
❗ (정답 : 4) why...?출처 : https://262.ecma-international.org/5.1/#sec-7.9
When a ++ or -- token is encountered where the parser would treat it as a postfix operator, and at least one LineTerminator occurred between the preceding token and the ++ or -- token, then a semicolon is automatically inserted before the ++ or -- token.
one++(1) + ++one((one++;++one((1+1)+1))
와 같이 후위 연산자를 했던 변수가 같은 문장 내에서 재활용 될때는 semicolon이 자동적으로 insert되어 실행되는것으로 해석하면 되겠다. (... 헷갈리긴 한다)
const value = ture;
console.log(!value); //false
console.log(!!"A"); //true
console.log(!null); //true (null,undefined,0,"" 는 논리로 치면 모두 false)
console.log(!"0"); // false ("0"은 String값이 있으므로 true)
유니코드(unicode)는 전세계 모든 문자에 대한 표준코드이다. 즉, 문자를 컴퓨터가 이해할 수 있는 숫자로 매핑해주는 매핑 테이블이라고 생각하면 된다.
0000~FFFF 혹은 10000~1FFFF(다섯숫자는 ES6부터..) 내에 각 숫자가 하나의 문자를 담당하고 있다.
console.log("\u0031") //1
UTF(Unicode Transformation Format) 는 이름에서도 알 수 있듯이, 유니코드를 변환하는 규칙이다.
왜 이미 숫자인 유니코드를 변환하는지? 어떻게 변환하는지? 변환의 장점은 뭔지?
유니코드와 UTF는 유니코드와 UTF 이해하기에서 좀 더 자세히 다루겠다.
❗ 유니코드 : 전세계 문자 -> 숫자매핑
❗ UTF : 유니코드 -> 컴퓨터 저장을 위한 숫자 변환
관계 연산자의 종류에는
<
,>
,<=
,>=
연산자, instanceof
,in
연산자가 있지만, instanceof
나 in
연산자는 instanceof 연산자, in 연산자에서 다루기로 한다.
>
연산자 : Greater-thanNumber
type일 때 : 왼쪽이 오른쪽보다 크면 true
, 아니면 false
returnString
type 비교String
타입이면 false (이전에 언급되었듯이, 말이 안되어 에러를 내야하는 상황이지만, 자바스크립트는 에러를 내지 않도록 발악하고있다..)String
타입이면, 유니코드 사전 순서로 비교 : 문자 차례대로 '하나씩' 비교하다가 값이 결정되면, 그 다음 문자는 비교되지 않는다(*아래 예시 참조)>
,<=
,>=
연산자 모두 비교기준만 다르지, 그 외에는 위와 모두 동일하다.//양쪽이 모두 숫자인 경우(숫자변환이 가능한 경우)
console.log((1+2) >1); //true (3>1)
console.log((1+2) >"1"); //true (3>1)
console.log((1+2) <null); //false (3<0)
//한쪽이 String인 경우(숫자변환 불가능)
console.log(1>"A"); //false
//양쪽이 String인 경우(숫자변환 불가능)
console.log("ACD">"ABC"); //true
맨 마지막의 경우,(A,A)
의 유니코드는 동일하기 때문에 각 다음 문자인 (C,B)
의 유니코드를 비교한다. C의 유니코드가 B의 유니코드보다 크므로 true
를 반환하고, 맨 뒤에 (D,C)
비교는 이루어지지 않는다.
true
,다르면 false
returntrue
,같으면 false
returntrue
, 값 또는 타입이 다르면 false
returntrue
,같으면 false
returnconsole.log(1=="1") //true
console.log(2!="2") //false
console.log(1==="1") //false
console.log(2!=="2") //true
let value;
console.log(value == undefined) //true
console.log(value == null) //true (undefined == null?????)
console.log(value === undefined) //true
console.log(value === null) //false
❓
null==undefined
: null과 undefined의 값이 동일하다? data type이 다른것은 이해했지만, 이 둘의 값이 동일하다는 것은 이해할 수 없는걸... 왜인지 검색을 해봤다.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
Traditionally, and according to ECMAScript, all primitives and objects are loosely unequal to undefined and null. But most browsers permit a very narrow class of objects (specifically, the document.all object for any page), in some contexts, to act as if they emulate the value undefined. Loose equality is one such context: null == A and undefined == A evaluate to true if, and only if, A is an object that emulates undefined. In all other cases an object is never loosely equal to undefined or null.❗ 브라우저에서 사용성을 위해 예외를 둔 사항중에 하나인 케이스같다.
let value,zero=0,one=1,two=2;
console.log(value||zero||two); // 2
console.log(zero||value); // undefined
console.log(value&&zero&&two); // undefined
console.log(one&&two); // 2
❓
let value,zero=0; console.log(value||zero||two);
실행시 two를 선언하지도 않았기 때문에 error 가 날것인가 생각해보자.
❗two
실행전에 이미 연산이 끝나기 때문에 이 경우에선 error가 나지 않는다.
❓왜 논리 결과(true,false)가 아니라 값 자체를 반환할까?
❗||
,&&
연산자 모두, 차례대로 연산을 하다가 전체 결과를 뒤바꿀 수 있는 가장 첫번째 요소를 반환한다 (없으면 마지막 요소).
개발자 입장에서보면, 반환된 값을 통해 true 혹은 false가 된 이유를 알 수 있어 디버깅이 쉽다.(실제로 이 이유에서인지는 모르겠다...)
true
이면, exp-1의 결과 반환false
이면, exp-2의 결과 반환`if
를 활용할 수 있지만, 간단한 조건과 결과면 조건 연산자
활용해서 간단하게 표현가능console.log(1=="1" ? "equal":"unequal") // equal
console.log(1==="1" ? "equal":"unequal") // unequal