October 29th 2018
목차 - var, let and const - Arrow function
var는 함수 단위로 스코프가 형성이 되고, ES6의 let과 const는 block 단위로 스코프가 형성됩니다. let과 const역시 var와 같이 hoisting이 되지만, temporal deadzone이 생겨서 var와는 다르게 값이 변수에 할당되기 전까지 사용할 수는 없습니다.
let 변수는 var 변수와 비슷한 역할을 하지만, var 변수와는 다르게 block 단위로 스코프를 형성합니다. 아래의 코드에서 tmp 변수를 console.log로 부르면 에러가 발생합니다.
function order(x, y) {
if (x > y) {
let tmp = x;
x = y;
y = tmp;
}
console.log(tmp === x); // ReferenceError: tmp is not defined
return [x, y];
}
아래의 코드에서 json의 kill 메소드 안의 target은, 해당 함수 안의 스코프에서만 존재하게 되고 스코프 밖의 operator 변수에는 영향을 주지 않아 operator.codename이 reference error가 발생하지 않고 콘솔에 'onion'이 출력됩니다.
{
let jason = {
codename: 'blackbriar',
kill: function(target) {
target = null;
}
};
let operator = {
codename: 'onion',
answer: function() {
alert('run away!');
}
};
jason.kill(operator);
console.log(jason.codename);
console.log(operator.codename);
}
let은 또한 window의 속성으로 추가되지 않습니다.
let temp = 'this is a temp variable.';
console.log(window.temp); // --> undefined
- hoisting & temporal deadzone 자바스크립트에는 기본적으로 호이스팅이 존재합니다. 변수가 선언이 되면 그 변수를 해당 스코프의 최상위로 끌어올려 줍니다. 하지만 hoisting에 있어서 var / let & const는 차이점이 존재합니다. MDN 문서를 참고하면 아래와 같습니다.
Temporal dead zone```javascript function doSomething() { console.log(bar); // undefined console.log(foo); // ReferenceError var bar = 1; let foo = 2; } doSomething(); ``` 변수 var의 경우 호이스팅이 되고 undefined로 초기값이 설정이 되지만, let의 경우는 호이스팅은 되지만 초기값이 설정되지는 않습니다. 변수에 값이 선언되기 전까지를 'temporal dead zone'이라 부르고, 이 지점에 let 변수에 접근을 하게 되면 Reference error가 발생합니다.
let bindings are created at the top of the (block) scope containing the declaration, commonly referred to as "hoisting". Unlike variables declared with var, which will start with the value undefined, let variables are not initialized until their definition is evaluated. Accessing the variable before the initialization results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the initialization is processed.
- cannot be re-declared
let temp = 'this is a temp variable.';
let temp = 'this is a second temp variable.'; // --> 에러 발생함.
- for loop using let variable for loop에서 var 변수를 사용하면 변수가 storage space에 binding이 됩니다.
const arr = [];
for (var i = 0; i < 3; i++) {
arr.push(() => i);
}
arr.map(x => x()); // [3, 3, 3]
for loop에서 let 변수를 사용하면 var 변수와는 다르게 변수가 각 loop iteration에 binding이 됩니다.
const arr = [];
for (let i = 0; i < 3; i++) {
arr.push(() => i);
}
arr.map(x => x()); // [0, 1, 2]
const는 let과 동일하게 동작하지만, 값이 바로 할당되어야 합니다. 그리고, 변수에 재선언 및 재할당을 할 수 없습니다.
const foo; // SyntaxError : Missing initializer in const declaration
const bar = 123;
bar = 456; // TypeError: Assignment to constant variable
for of 문은 각 loop 별 새로운 바인딩이 생기기 때문에 loop에서 const를 이용해도 문제가 없습니다.
for (const x of ['a', 'b']) {
console.log(x); // --> 'a' 'b' 가 출력됨.
}
Arrow function은 syntax가 간소화 된 형태로 사용할 수 있습니다. 먼저, MDN의 화살표 함수 정의를 살펴보겠습니다.
An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords. Arrow function expressions are ill suited as methods, and they cannot be used as constructors.
화살표 함수에서 중요하게 집고 넘어가야 할 점은, 내부 this, arguments, super가 없다는 점 입니다. 그리고 'arrow function expression'이라고 나와있습니다. 바꿔말하면, function declaration으로는 사용할 수 없습니다.
const name = 'window';
const obj = {
name: 'Chanwhe',
logName: () => {
console.log(this.name);
}
};
obj.logName(); // => 'window' 가 출력됨.
위의 코드를 실행하면 콘솔에 'window'가 출력됩니다.
const name = 'window';
function foo() {
const obj = {
name: 'Chanwhe',
logName: () => {
console.log(this.name);
}
};
obj.logName(); // 'kim' 이 출력됨.
}
foo.call({ name: 'kim' });
위의 코드를 실행하면 콘솔에 'kim'이 출력됩니다.