🏗

[JS] 바인딩


Expression(표현식) and Statements(구문)

값(value)를 생성하는 코드 조각을 expression이라고 부른다.

괄호에 들어있는 표현식도 표현식이고, 두 가지 표현식이 적용된 이항 연산자나, 하나의 식이 적용된 단항 연산자도 마찬가지로 표현식이다. 삼항 연산자 또한 값을 어떤 식의 참과 거짓을 판단해서 값을 반환하니 표현식이다.

1"이것은 표현식이여"
2a && b
3!true
4false ? "진실" : "거짓"

expression을 문장의 구성요소라고 하면, statement는 문장을 뜻한다. 그리고 프로그램은 statement의 덩어리다. 가장 간단한 형태의 구문은 표현식과 세미클론으로 표현할 수 있다.

11;
2!false;

위에 구문은 그냥 표현식과 다를바 없다. 값을 생성한 후 이 값으로 아무것도 하지않기 때문이다.

구문은 프로그램에 영향을 미칠 때만 뭔가 의미있는 부분으로써 존재한다. 예를 들면, 뭔가 화면에 보여주거나 기계 내부 상태를 변화시키는 등의 동작이다. 이런 변화들을 side effects(부수 효과)라고 한다.

Binding

그럼 위에서 만든 값을 저장하려면 어떻게 해야할까? 자바스크립트에서는 값을 잡아 두기 위해 'binding(variable/변수)'를 제공한다.

1let caught = 1;

let이라는 'keyword'는 이 구문이 binding을 한다는 것을 나타낸다. 뒤따르는 caught는 바인딩의 이름을 나타낸다. 바인딩을 생성하면 내가 생성한 이름을 `expression'으로 사용할 수 있다.

varconst 키워드로도 바인딩을 생성할 수 있다. varlet과 유사한 방법으로 바인딩을 생성해준다. 하지만 var은 좀 햇갈리는 특성이 많아서 사용하는걸 권장하지 않는다. 이를 보완하기 위해 ES6 이후에 나온 방식이 let이다. const는 'constant'를 뜻한다. 말그대로 살아있는 동안은 똑같은 값을 잡고있는다는 뜻이다.

var의 문제점

var 키워드는 크게 세 가지 문제점을 가진다.

첫 번째로, 같은 변수 이름으로 재선언을 허용한다. 아래 예를 보자.

1var test = "안녕";
2console.log(test); // 안녕
3var test = "뭘봐";
4console.log(test); // 뭘봐

각기 다른 값으로 정상적으로 출력이 된다. 간단한 코드의 경우 문제가 되지 않을 수도 있지만, 코드가 길어진다면 변수의 타입과 값이 언제 어디서 바뀌는지 파악하기 어려워질 우려가 있다.

두 번째로, 호이스팅(Hoisting) 후 undefined로 초기화되기 때문에 선언이 어디에 있던 상관없이 참조가 가능하다. 인터프리터는 변수의 선언과 할당을 분리하여 변수의 선언을 항상 컨텍스트 내의 최상위로 끌어올리는데, 이것을 '호이스팅'이라고 한다. let이나 const의 경우 호이스팅이 일어나지면 할당은 되지 않기 때문에 참조 에러가 발생하게 된다. 하지만 var는 호이스팅 이후 undefined가 자동 할당된다.

1console.log(test); // undefined
2var test = "안녕?";

그렇기 때문에 위와 같이 test를 출력해보면 undefined가 나온다.

세 번째로, var은 함수 범위 스코프를 가지기 때문에, 함수 밖에서 사용하면 전역 변수가 된다. 아래 예를 보자.

1let x = 10;
2if (true) {
3 let y = 20;
4 var z = 30;
5 console.log(x + y + z); // -> 60
6}
7// y는 사용될 수 없다.
8console.log(x + z); // -> 40

함수가 아닌 곳에서 var 키워드를 이용해 z를 선언했기 때문에 전역 변수로 취급된다. 스코프에 관한 자세한 내용은 여기서 다룬다.

위와 같은 특징들 때문에 var를 사용할 경우 변수가 언제 어디서 변경됐는지 알기 힘들어진다. 그러니까 사용하지 말자.

Functions

function(함수)값으로 포장된 프로그램이다. 포장한 값을 사용해서 프로그램을 호출할 수 있다. 예를 들어, 브라우저의 prompt 바인딩은 함수이다. prompt를 호출하면 사용자 입력을 요구하는 작은 상자를 표시할 수 있다.

1prompt("비밀번호를 입력하세요");

함수는 함수 값을 생성하는 표현식 다음에 괄호를 사용하면 호출할 수 있다. 괄호 안의 값은 함수 내부에 전달되게 된다. 위의 prompt에선 문자열을 받아 박스 안에 보여준다. 이렇게 함수 내부에 전달되는 값을 arguments라고 한다.

함수가 값을 뱉어내면, 이걸 "값을 return한다"라고 한다. 자바스크립트에서는 값을 만드는 모든 것은 expression이므로 함수를 호출하는 것도 표현식이다.


참조:
Eloquent JavaScript
https://www.howdy-mj.me/javascript/var-let-const/