이 기록은 inflearn의 자바스크립트 비기너: 튼튼한 기본 만들기의 강좌를 들으면서 보충자료와 함께 제 나름대로의 문장으로 재구성한 내용입니다.

1. 연산자,표현식(Operators,Expressions)

연산자(Operators)

연산의 사전적 의미는 규칙에 따라 계산하여 값을 구함이다. 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 등등)❗

표현식(Expressions)

표현식은 값으로 이행하는 임의의 유효한 코드 단위(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는 두 표현 결과를 더하는 표현식)

(연산 계산: "표현식 평가"), (반환된 값: "평가 결과)"❗

javascript는 표현식의 연결이다❗


2. 할당 연산자(assignment operators)

  • 단일 할당 연산자
    • = 하나만 사용
  • 복합 할당 연산자
    • = 앞에 연산자 작성
      +=,-=,*=,/=,%=
      <<=,>>=
      <<<=,&=,%=,|=
    • 먼저 = 앞을 연산한 후, 할당
    let value = 3;
    value+=2; //var+2를 연산한 후, 할당, var=var+2;와 같은 해석
    console.log(value); //5

3. 산술 연산자(+연산자)

  • + 양쪽의 표현식을 평가 ( 각 평가결과를 더함)
  • 왼쪽에서 오른쪽으로 연산
  • 평가 결과 연결 : 한쪽이라도 숫자가 아니면 연결 (일반적으로, 에러가 나오는게 정상인듯 하지만, 에러가나서 전체 웹페이지가 표시되지 않는 상황을 최대한 방어하려는 방향성을 가지는 언어이기때문에 이런 메카니즘이 나온다)
const two = "2";
const value = 1+3+two ; // 42, 한쪽이라도 평가결과가 Number타입이 아니면 평가결과를 더하지 않고 연결
console.log(typeof value); // string

javascript는 에러가 나지않기 위해 발악(?)하고 있다❗

javascript에서 + 연산자는 한쪽이라도 평가결과가 Number 타입이 아니면 평가결과를 연결한다❗


4. 숫자로 변환

  • 연산하기 전에 우선 숫자로 변환 시도
값 타입변환 값
undefinedNaN
Null0
Booleantrue: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아닐 경우, 연결)

javascript에서 +연산자를 제외하고 연산 전 숫자 변환을 시도한다❗


5. 산술 연산자(-,*,/,% 연산자)

  • -연산자 : 왼쪽 표현식 평가 결과에서 오른쪽 표현식 평가 결과 뺌,
    • String 타입이지만, 값이 숫자이면 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
  • *연산자 : 왼쪽 표현식 평가 결과에서 오른쪽 표현식 평가 결과를 곱함,
    • String 타입이지만, 값이 숫자이면 Number 타입으로 변환하여 계산(+와는 다름)
    • 소수 값(IEEE 754 부동 소수점) 이슈 : javascript뿐만 아니라 엑셀 등 컴퓨터에서 소수 활용시 이슈가 있다
// 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) // 대응방법: 실수를 정수로 변환하여 값을 구하고, 당시 절수를 실수로 변환
  • /연산자 : 왼쪽 표현식 평가 결과에서 오른쪽 표현식 평가 결과를 나눔
    • String 타입이지만, 값이 숫자이면 Number 타입으로 변환하여 계산(+와는 다름)
    • NaN 반환 : 분모,분자 모두 0일 때
    • Infinity 반환 : 분모가 0일 때
// 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
  • %연산자 : 왼쪽 표현식 평가 결과를 오른쪽 표현식 평가 결과로 나누어 나머지를 구함
    • String 타입이지만, 값이 숫자이면 Number 타입으로 변환하여 계산(+와는 다름)
    • 소수 값(IEEE 754 부동 소수점) 이슈 : javascript뿐만 아니라 엑셀 등 컴퓨터에서 소수 활용시 이슈가 있다
// 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) // 대응방법: 실수를 정수로 변환하여 값을 구하고, 당시 절수를 실수로 변환

6. 단항 연산자

단항 + 연산자

  • 형태 : +value
  • 값을 Number 타입으로 변환(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

단항 - 연산자

  • 형태 : -value
  • 값의 부호를 바꿈 : +는-로, -는 +로, 연산시에만 바꿈(원래 값은 바뀌지 않음)
  • 코드가독성 : value*(-1)과 같은 형태로 추천
let value = "7"
console.log(-value) //-7
console.log(8 + -value) //1
console.log(value) //"7"

7. 후치,전치,논리 NOT 연산자

후치 +,- 연산자

  • 형태 : value++ ,value--
  • 값을 1증가/감소시킴 : 문장 수행후에 1증가/감소(표현식 평가후 1증가/감소, 표현식에서는 원래값 사용)
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

전지 +,- 연산자

  • 형태 : ++value, --value
  • 값을 1증가/감소시킴 : 문장 에서 1증가/감소(표현식 평가전 1증가/감소, 표현식에서 증가/감소된 값 사용)
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되어 실행되는것으로 해석하면 되겠다. (... 헷갈리긴 한다)

! 연산자

  • 논리(logical) NOT 연산자
  • 형태 : !value
  • 표현식 평가 결과를 true,falue로 변환한 후, true이면 false, false이면 true 반환
  • 원래값은 바뀌지 않으며, 연산시에만 변환
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)

8. 유니코드,UTF

유니코드(unicode)는 전세계 모든 문자에 대한 표준코드이다. 즉, 문자를 컴퓨터가 이해할 수 있는 숫자로 매핑해주는 매핑 테이블이라고 생각하면 된다.

0000~FFFF 혹은 10000~1FFFF(다섯숫자는 ES6부터..) 내에 각 숫자가 하나의 문자를 담당하고 있다.

  • 표기방법 : u와 숫자형태 : u0031은 숫자1
    • javascript에서는 u앞에 역슬래쉬()를 활용한다.
      console.log("\u0031") //1

UTF(Unicode Transformation Format) 는 이름에서도 알 수 있듯이, 유니코드를 변환하는 규칙이다.
왜 이미 숫자인 유니코드를 변환하는지? 어떻게 변환하는지? 변환의 장점은 뭔지?
유니코드와 UTF는 유니코드와 UTF 이해하기에서 좀 더 자세히 다루겠다.

❗ 유니코드 : 전세계 문자 -> 숫자매핑
❗ UTF : 유니코드 -> 컴퓨터 저장을 위한 숫자 변환


9. 관계 연산자

관계 연산자의 종류에는
<,>,<=,>= 연산자, instanceof,in 연산자가 있지만, instanceofin연산자는 instanceof 연산자, in 연산자에서 다루기로 한다.

  • >연산자 : Greater-than
    • 양쪽이 Numbertype일 때 : 왼쪽이 오른쪽보다 크면 true, 아니면 false return
    • Stringtype 비교
      • 숫자로 변환가능시, 숫자로 변환 후 진행
      • 그 외, 한쪽이 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) 비교는 이루어지지 않는다.


10. 동등,부등,일치,불일치,연산자

== 연산자

  • 동등 연산자 : 왼쪽값과 오른쪽값이 같으면 true,다르면 false return
  • data type은 비교하지 않는다(1과 "1"은 같음)

!= 연산자

  • 부등 연산자 : 왼쪽값과 오른쪽값이 다르면 true,같으면 false return
  • data type은 비교하지 않는다

=== 연산자

  • 일치 연산자 : 왼쪽과 오른쪽의 값과 타입이 모두 같으면 true, 값 또는 타입이 다르면 false return

!== 연산자

  • 부등 연산자 : 왼쪽값과 오른쪽값이 다르면 true,같으면 false return
  • data type은 비교하지 않는다
console.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.

❗ 브라우저에서 사용성을 위해 예외를 둔 사항중에 하나인 케이스같다.


11. 논리 연산자

|| 연산자

  • 논리 OR 연산자
  • 표현식의 평가 결과가 하나라도 true 이면 true, 아니면 false (하나라도 true이면, 전체 true로 끝)
  • 차례대로 연산을 하다가 true이면 해당값을 리턴하고(true를 리턴하지 않고 값을 리턴), 나머지는 비교하지 않음 (즉, 제일 먼저 true를 유발한 요소를 리턴하고 끝남, 하나라도 true라면 뒤를 볼 필요 없음)
  • 마지막까지 비교하였는데, 모두가 false이면 false가 아니라 마지막 값을 리턴 (즉, true를 유발한 요소가 없으면, 마지막 요소 리턴하고 끝남)

&& 연산자

  • 논리 AND 연산자
  • 표현식의 평가 결과가 모두 true 이면 true, 아니면 false (하나라도 false이면, 전체 false로 끝)
  • 차례대로 연산을 하다가 false이면 해당값을 리턴하고(false를 리턴하지 않고 값을 리턴), 나머지는 비교하지 않음 (즉, 제일 먼저 false 유발한 요소를 리턴하고 끝남, 하나라도 false라면 뒤를 볼 필요 없음)
  • 마지막까지 비교하였는데, 모두가 true이면 true가 아니라 마지막 값을 리턴(즉, false를 유발한 요소가 없으면, 마지막 요소 리턴하고 끝남)
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가 된 이유를 알 수 있어 디버깅이 쉽다.(실제로 이 이유에서인지는 모르겠다...)


12. 조건 연산자, 연산자 우선순위

조건 연산자

  • 기호 : exp?exp-1:exp-2 (3항 연산자라고도 함)
  • exp 위치의 표현식을 먼저 평가하고,
    • true이면, exp-1의 결과 반환
    • false이면, exp-2의 결과 반환`
  • if를 활용할 수 있지만, 간단한 조건과 결과면 조건 연산자 활용해서 간단하게 표현가능
    console.log(1=="1" ? "equal":"unequal") // equal
    console.log(1==="1" ? "equal":"unequal") // unequal

연산자 우선순위

mozilla MDN Web Docs 참고하기


내용에 오류가 있다면, 알려주시면 감사합니다.

0개의 댓글