[ECMAScript 6] let - block 단위 스코프
ECMAScript 6에서는 기존의 function scope였던 >var
이외에 >let
이라는 block scope 변수 선언을 지원한다. >let
을 통한 변수 선언은, >var
를 통한 변수 선언과 다르게 hoisting 하지 않는다. 즉, 변수가 선언된 이후부터 변수가 유효하고 그전에는 해당 변수를 사용할 수 없다.
function es5() { | |
var i; | |
for (i = 0; i < 10; i += 1) { | |
doSomething(); | |
} | |
// i is 10 | |
} | |
function es6() { | |
for (let i = 0; i < 10; i += 1) { | |
doSomething(); | |
} | |
// i is not declared | |
} |
hoisting을 없앤 것뿐 아니라 그 외의 실수하기 쉬운 부분을 에러로 처리하여 좀 더 안전한 코드를 작성할 수 있도록 하였다. 예를 들면, ECMAScript 5에서는 hoisting 된 변수를 실수로 선언 전에 사용할 경우 그 변수는 >undefined
가 된다. 하지만 >let
을 사용하면, 변수를 hositing 하지 않을 뿐 아니라, 변수를 선언한 블록 안에서 선언 전에 해당하는 이름을 사용하는 것을 에러로 처리한다.
function es5() { | |
var i; | |
for (i = 0; i < 10; i += 1) { | |
(function () { | |
doSomething(i); // i is undefined, because the variable(declared at line 8) is hoisted | |
{ | |
doSomething(i); // it is also undefined, because the variable(declared at line 8) is hoisted | |
var i = 10; | |
} | |
})(); | |
} | |
} | |
function es6() { | |
for (let i = 0; i < 10; i += 1) { | |
(function () { | |
doSomething(i); // 0 to 9 | |
{ | |
doSomething(i); // syntax error | |
let i = 10; | |
} | |
})(); | |
} | |
} |
또한, 이전에는 같은 스코프, 다시 말해서 같은 함수 안에서 변수의 선언문이 여러 개 있는 것이 정상적인 구문으로 처리되었다. 하지만 >let
을 사용한다면 같은 스코프에서 중복으로 선언하는 것이 에러로 처리된다.
function es5() { | |
var i; | |
for (i = 0; i < 10; i += 1) { | |
(function () { | |
var i = 10; | |
var i = i + 1; | |
doSomething(i); // i is 11 | |
})(); | |
} | |
} | |
function es6() { | |
for (let i = 0; i < 10; i += 1) { | |
(function () { | |
let i = 10; | |
let i = i + 1; // syntax error because of redeclaration of i | |
doSomething(i); | |
})(); | |
} | |
} |
아쉬운 점은 위와 같은 에러가 함수의 선언에서 발생하는 것이 아니라, 실제로 그 구문을 실행할 때 발생한다는 것이다. 따라서 여전히 높은 커버리지의 테스트를 작성해야 안전한 코드라고 보장할 수 있다. 하지만 예전처럼 예상하지 못한 >undefined
가 나와서 문제가 발생한 부분이 아닌 다른 곳부터 추적해가야 할 일은 없어졌다.
또 다른 문제는 babel에서 다르게 동작한다는 것이다. 파이어폭스나 크롬 등 모던 브라우저나 io.js는 ECMAScript 6를 지원하지만, 오래된 버전의 IE나 node.js 등에서는 아직 >let
을 지원하지 않는다. 그런 환경에서는 babel을 사용해야 하는데, babel에서는 중복된 선언이나, 선언 전에 사용하는 것을 에러로 처리하지 않는다.
하지만 조만간 node.js에서도 >let
을 지원할 것이고, 오래된 버전의 IE도 없어지고 있으니 이런 문제는 곧 해결될 것이다.
댓글
댓글 쓰기