문법
자바스크립트 언어에서 구문이 어떻게 작동하는지 알아보자. 자바스크립트 코딩 실력을 자신하는 사람도 자바스클비트 언어의 문법은 어려워한다. 온갖 혼란과 오해의 늪에 빠지게 할, 별별 미묘한 것들로 가득차 있어서다. 자, 이런 것들을 확실히 끄집어내어 그간 우리가 잘못 알아온 것들을 말끔히 정리하자.
문과 표현식
문과 표현식을 대충 같은 의미라고 넘겨버리는 개발자가 허다하다. 그러나 자바스크립트에서 두 용어는 아주 중요한 차이가 있으므로 명확하게 분별하자.
문장은 생각을 표현하는 단어들의 완전한 조형물이다. 문장은 하나 이상의 어구로 구성되며 각 어구는 구두점이나 접속사로 연결할 수 있고 어구는 더 작은 어구로 나눌 수있다. 어던 어구는 불완전하여 그 자체로 완성된 문장을 형성할 수 없지만 스스로의 힘만으로 완성되는 어구도 있다. 이러한 규칙들을 통틀어 영어 언어의 문법이라고 한다.
자바스크립트 문법도 마찬가지다. 문은 문장, 표현식은 어구, 연산자는 구두점/접속사에 해당된다. 자바스크립트에서 모든 표현식은 단일한, 특정한 결괏값으로 계산된다. 예를 들면
var a = 3 * 6;
var b = a;
b;
여기서 3 * 6
은 표현식이다. 두 번재 줄 역시 표현식이며, 세 번재 줄도 표현식이다. a, b 표현식 모두 당시 변수들에 저장된 값으로 평가되므로 b역시 18이 된다.
게다가 이 세 줄은 각각 표현식이 포함된 문이다. var a = 3 * 6
, var b = a
두 문은 각각 변수를 선언(그리고 선택적으로 동시에 어떤 값을 할당) 하므로 '선언문'이라 한다. a = 3 * 6
나 b = a
는 '할당 표현식'이라고 한다.
세 번째 줄은 b가 표현식의 전부지만 이것만으로 완전한 문이다. 일반적으로 이런 문을 '표현식 문'이라고 한다.
문의 완료 값
모든 문은 완료 값을 가진다는 사실을 의외로 모르는 사람들 이많다.
문의 완료 값은 들여다볼 방법이 없을까?
가장 확실한 방법은 브라우저 개발자 콘솔 창에서 문을 타이핑 해보는 것이다. 콘솔 창은 가장 최근에 실해된 문의 완료 값을 기본적으로 출력하게 되어있다.
var b = a
같은 문은 완료 값이 뭘까?
할당 표현식 b = a
는 할당 이후의 값이 완료 값이지만, var 문 자체의 완료 값은 undefined
이다. 명세에 그렇게 적혀있기 때문이다. 실제로 var a = 42
를 콘솔창에서 실행해 보면 42대신 undefined가 나온다.
콘솔 창에서 여러 가지 코드를 테스트해본 사람이라면 문의 실행 결과가 undefined
로 표시되는 걸 자주 목격했을 텐데, 대체 이게 뭔지 진지하게 고민해본 적은 한 번도 없을 것이다. 한 마디로 콘솔은 시랳ㅇ한 문의 완료 값을 보고한 것이다.
그러나 콘솔 창이 내어준 완료 값은 개발자가 내부 프로그램에서 사용할 수 있는 값은 아니다.
방법은 있겠지만 꽤 복잡한 작업ㅇ디ㅏ. 그런데 방법을 설명하기 앞서, 왜 꼭 그래야 하는지부터 생각하자.
다른 종류의 문 완료 값을 보자. 예를 들어 보통의 {}
블록은 배ㅜ의 가장 마지막 문표현식의 완료 값을 자신의 완료 값으로 반환한다.
var b;
if (true) {
b = 4 + 38;
}
콘솔 창에서 실해아혐ㄴ 42가 나온다. 블록 내의 마지막 문 b = 4 + 38
의 완료 값이 42이므로 if블록의 완료 값도 42를 반환하게 된다.
즉, 블록의 완료 값은 내부에 있는 마지막 문의 값을 암시적으로 반환한 값이다.
하지만 다음과 같은 코드가 작동하지 않는 건 분명히 문제가 있다.
var a, b;
a = if(true){
b = 4 + 38;
};
문의 완료 값을 포착하여 다른 변수에 할다하는 건 쉬운 구문/문법으로는 불가능하다.
뭔가 방법이 없을까?
어디까지나 예를 들기 위함이니 다음 코드는 실제로 사용하지 말자.
원료 값을 포착하려면 어쩔 수 없이 유해함의 대명사 eval()
함수를 사용할 수 밖에 없다.
var a, b;
a = eval("if (true) { b = 4 + 38; }");
a; // 42
으휴, 꼴보기 싫은 코드지만 일단 잘 돌아간다. 콘솔 창 이외에 자바스크립트 프로그램에서도 문완료 값을 확인할 길이 있음을 알 수 있다.
ES7 명세에는 'do 표현식'이 제안된 상태이다. 다음 코드를 보자.
var a, b;
a = do {
if (true) {
b = 4 + 38;
}
};
a; // 42
do {}
표현식은 블록 실행 후 블록 내 마지막 문의 완료 값을 do표현식 전체의 완료 값으로 반환하며 결국 이 값이 변수 a에 할당된다.
인라인 함수 표현식 안에 감싸서 명시적으로 반환할 필요 없이 문을 표현식처럼 다루자는 게 기본적인 아이디어다.
아직까지는 문 완료 값을 대수롭지 않게 여기고 있지만 자바스크립트 언어가 진화할수록 그 중요성은 점점 더 부각될 것 같다. do {}
표현식이 도입되어 eval()
같은 나쁜 것들을 사용하고픈 욕구를 영원히 잠재울 수 있길 고대한다.
노파심에 다시 경고하지만 eval()은 사용하지 말자..!!!!!
참고
- You Don't Know JS - 타입과 문법, 스코프와 클로저( 한빛 미디어 )
'JAVASCRIPT' 카테고리의 다른 글
[JS][문법] 콘텍스트 규칙 (0) | 2022.02.14 |
---|---|
[JS][문법] 표현식의 부수 효과 (0) | 2022.02.13 |
[JS][강제변환][마무리] 추상 관계 비교 (0) | 2022.02.13 |
[JS][강제변환] 동등비교 : 희귀 사례 (2) (0) | 2022.02.13 |
[JS][강제변환] 동등비교 : 희귀 사례 (1) (0) | 2022.02.12 |
댓글