민규의 개발블로그
자바스크립트 문법 본문
문과 표현식
자바스크립트에서의 문은 문장, 표현식, 어구, 연산자는 구두점/접속사에 해당된다. 자바스크립트에서 모든 표현식은 단일한, 특정한 결괏값으로 계산된다.
3 * 6은 표현식이다. 두 번째 줄 역시 표현식이며, 세 번째 줄 b도 표현식이다.
a, b 표현식 모두 당시 변수들에 저장된 값으로 평가되므로 b 역시 18이 된다.
이 세줄은 각각 표현식이 포함된 문이다. var a = 3 * 6, var b = a 두 문은 각각 변수를 선언하므로 '선언문'이라 한다.
a = 3 * 6나 b = a는 '할당 표현식'이라고 한다.
세 번째 줄은 b가 표현식의 전부지만 이것만으로도 완전한 문이다. 일반적으로 '표현식 문'이라고 일컫는다.
표현식의 부수 효과
표현식은 순수하고 독립적이지만 부수 효과를 일으킬 수 있다.
증감 연산자(++, --)는 전위 연산자로 사용하면 표현식으로부터 값이 반환되기 전에 (1만큼 증가시키는) 부수 효과를 일으킨다. 후위 연산자로 사용하면 반환한 이후에 부수 효과가 발생한다.
delete 연산자의 결괏값은 유효한/허용된 연산(존재하지 않는 프로퍼티 또는 존재하면서 설정 가능한 프로퍼티)일 경우 true, 그 외에는 false다.
delete 역시 부수 효과를 일으키는 연산자다. 이 연산자의 부수 효과는 프로퍼티를 제거하는 것이다.
= 할당 연산자도 부수 효과 유발 연산자다.
할당 표현식/문 실행시 할당된 값이 완료 값이 되는 작동 원리는 다음과 같은 연쇄 할당문에서 특히 유용하다.
c = 10 평가 결과는 10이 되고 b = 10의 평과 결과는 10을 b에 할당하는 부수 효과를 일으키며 10이된다. 결국 a = 10으로 평가된다.
할당 연산자의 부수 효과를 잘 활용한 예
연산자 우선 순위
자바스크립트 연산자는 그 우선순위와 결합성이 분명히 정해져 있다. 우선순위/결합성 규칙을 잘 알아두면 짧고 깔끔한 코딩에 도움이 된다.
아래 결괏값은 왜 다를가? 이유는 , 연산자가 = 연산자보다 우선순위가 낮기 때문이다. 그러므로 d = c++,c를 엔진은
(d=c++), c로 해석한다
간단히 &&가 =보다 우선순위가 높으므로 =를 먼저 실행 시켜주고자하면 ( )를 해주고
&&는 || 보다 우선순위가 높다.
단락 평가
우선 && 연산자와 || 연산자에 대해에 특성을 잠깐 언급하자면 &&, || 연산자는 좌측 피연산자의 평가 결과만으로 전체 결과가 이미 결정될 경우 우측 피연산자의 평가를 건너뛴다.
예를 들어 a && b 에서 a가 false면 b는 보지도 않고, a || b 에서 a가 true면 b는 보지도 않고 전체 결괏값은 true 확정된다.
유용하게 쓰인 예
opts && opts.cool에서 opts는 일종의 가드다. opts가 존재하지 않는다면 당연히 opts.cool은 에러일 수 밖에 없다.
그러니 opts를 먼저 단락 평가 해보고, 그 결과가 실패면 opts.cool은 자동으로 건너뛰니 결과적으로 에러가 나지 않는다.
결합성
연산자는 처리 방향이 좌측 > 우측이냐, 우측 > 좌측에 따라 결과가 다르다.
삼항 연산자 ? : 는 &&, || 보다 우선순위가 낮다.
a ? b : c ? d : e 이건 어떻게 실행 될까?
답은 a ? b : (c ? d: e)다. ? : 는 우측부터 실행된다.
? : 는 우측 결합성을 가짐 . ( = 도 포함)
&& 와 || 연산자는 좌측 결합성을 가진다.(그렇지만 별로 중요하진 않음)
이것을 토대로 (a && b && c)와 같은 코드를 결합성을 고려하여 순서를 명시하고자
((a && b) && c) 같이 하지는 말고 ? : 조건 연산자가 체이닝된 코드가 있다면 주저없이 ( )로 그룹핑하여 의도한 로직을 확실히 밝히자.
세미콜론 자동 삽입
ASI(자동 세미콜론 삽입)는 자바스크립트 엔진에 내장된 '파서 에러 감지 시스템'으로 필요한 ; 이 코드에서 누락된 경우 파서 에러가 나면 자동으로 삽입해보고 코드 실행에 문제가 없도록 도와준다. 이런 장치가 있어서 ;을 쓸지 말지 의견이 분분하다.
깔끔한 코드를 의도해 뺄 수도 당연히 넣어야 되는 건데 안넣어서 ASI가 잡아주는 거니 넣어야 된다. 시각이 다양하기 때문에 본인이 판단하면 될 것 같다.(난 앞으로 넣을 거다.)
에러, 함수 인자
자바스크립트 에러는 여러 유형이 있지만 '조기에러'(컴파일러가 던진 잡을 수 없는 에러)와 '런타임 에러'(try catch로 잡을 수 있는 에러)로 분류 된다.
arguments 배열은 비 권장 요소지만 "인자와 이 인자에 해당하는 arguments 슬롯을 동시에 참조하지 마라"는 간단한 규칙만 준수한다면 arguments 배열과 인자를 섞어 사용해도 안전하다.
try finally
책을 읽으며 원래 try 이후에는 catch, finally 중 하나만 필수라는 걸 알고는 놀랐다.
finally 절의 코드는 다른 블럭 코드에 상관없이 필히 실행되어야 할 콜백 함수와 같다.
try 절에 return 문이 있을 경우?
return 10에서 a( ) 함수의 완료 값은 10으로 세팅되고, try 절의 실행이 종료되면서 곧바로 finally 절로 넘어간다.
그 후 a( ) 함수 전체의 실행이 끝나고 완료 값은 호출부 console.log( ) 문에 반환된다.
만약 finally 절에서 예외가 던져지면, 이전의 실행 결과는 모두 무시한다.
이전에 try 블록에서 생성한 완료 값이 있어도 모두 사장된다. 그리고 finally 절의 return은 이전의 try 나 catch 절의 return 을 덮어쓴다. 단 명시적으로 return문을 써야 한다.
보통 함수에서는 return을 생략해도 return; 또는 return undefined; 한 것으로 치지만,
finally 안에서 return을 빼면 이전의 return을 무시하지 않고 존중한다.
switch
switch는 if else if else 문의 사슬을 짧게 해준다.
switch 표현식과 case 표현식 간의 매치 과정은 === 알고리즘과 똑같다.
강제변환이 일어나는 동등 비교를 이용하고 싶다면 switch 문에서 꼼수를 부려야 한다.
아래는 case절에 표현식이 있으니 실행상 문제는 없다. a ==10은 true 이므로 가능. 하지만
표현식에 && 나 || 같은 논리 연산자에 경우 (truthy이지만 true는 아닌) 그럴 땐 안된다.
default 절은 선택 사항이며 꼭 끝 부분에 쓸 필요는 없다. 그렇지만 breack는 꼭 써주어야 된다 안 써주면 그 이후로 코드가 계속 실행됨.
'Javascript' 카테고리의 다른 글
자바스크립트 렉시컬 스코프 (0) | 2020.11.20 |
---|---|
자바스크립트 스코프 (0) | 2020.11.20 |
자바스크립트 강제변환-2 (0) | 2020.11.17 |
자바스크립트 강제변환-1 (0) | 2020.11.16 |
자바스크립트 네이티브 (0) | 2020.11.13 |