ES6에서“var”키워드를 사용해야 할 이유가 있습니까?


261

ES6에 대한 Babel의 가이드 는 다음과 같이 말합니다.

let새로운 것 var입니다.

명백하게 유일한 차이점이다 var현재 범위에 도착 기능 하면서, let현재의 범위에 도착 블록 . 이 답변 에는 좋은 예가 있습니다.

varES6 코드에서 사용해야 할 이유가 없습니다 . 주어진 변수를 전체 함수로 범위를 지정하려는 경우에도 let함수 블록의 맨 위에 선언을 넣어 var실제 범위를 나타 내기 위해 수행해야합니다 . 그리고 for블록이나 무언가 에서 더 세밀하게 범위 를 지정하려면 그렇게 할 수 있습니다.

그래서 내 본능은 varES6 코드를 작성할 때 완전히 사용을 중지하는 것 입니다.

내 질문은, 이것에 대해 잘못입니까? var보다 바람직한 합법적 인 사례가 let있습니까?


3
아직 시도하지 않았지만 (ES6 코드를 작성하지 않았기 때문에) var이 변수가 전체 기능에 적용되도록 의도 된 지표로 사용 하는 것이 유용한 "자체 문서화"규칙 일 수 있습니다. .
jfriend00

10
let함수 상단에 문장 을 넣으면 전체 함수에 범위를 지정하려는 것이 분명합니다. 나는 var그것을 사용 하는 것이 단순히 상단에있는 것보다 더 명확 하다고 생각하지 않습니다 .
callum

11
솔직히, 나는 var여전히 존재 하는 유일한 이유 는 이전 버전과의 호환성 이라고 믿습니다 . 그것이 아니라면, 그들은 var완전히 제거 되었거나 let처음부터 소개되지 var않았을 것입니다.
Jörg W Mittag

2
@RayToal 나는 Kyle Simpson이 말한 것의 97 %에 동의하지만, 계속 사용하는 그의 이유 var는 나에게는 얇아 보이지만, 제 3의 종류의 변수가 있다는 것을 보증하기에는 충분하지 않습니다. a let를 함수의 상단에 배치하여 간단히 전체 함수로 범위를 지정할 수 있습니다 var. 블록에서 쓰는 것보다 의도가 훨씬 명확 합니다 (블록에서 들어 올리면 블록 외부에서 사용할 수 있습니다) -이상하다). 그는 a let를 함수로 범위 를 지정하면 "구문이 아니라 차이점을 나타내는 위치에 불과하다" 고 경고 하지만, 이것이 좋은 것이라고 생각합니다.
callum 2016 년

2
@RayToal 나도이 기사를 읽고 (이 토론을 읽기 직전에) 그의 매우 약한 사례에 대해 정말 실망했습니다 var. 그가 유지하기 위해 제시 한 예는 생각 var이 많이 들었으며 심각한 코딩 오류를 기반으로 합니다. 오류가 발생하여 문제를 해결할 수있는 언어 기능을 사용하는 것보다 오류가 발생하여 해당 오류를 수정하는 것이 훨씬 좋습니다! 다음으로 충돌을 막기 위해 try / catch로 모든 것을 포장해야합니까? 그 링크의 나머지 부분은 훌륭하지만 그 특정 부분에 전혀 동의하지 않습니다.
Mörre

답변:


217

Doug Crockford let이 시점 에서 " 더 나은 부품 "에 대해 이야기 합니다.

요점은 let오해의 원인을 피하는 것입니다. 블록 범위를 가진 언어로 설정된 기대치를 가진 프로그래머에게 적합합니다. A를 var갖는 함수 범위 는 비록 (그것은 함수 통하여 볼의 변수 선언) 모양 은 가지고 같은 범위 블록 .

var 기계 생성 코드와 같은 극단적 인 경우에도 여전히 유용 할 수 있지만 열심히 노력하고 있습니다.

( const또한 새로운 및 범위를 차단할 수 있습니다. 후 let x = {'hi': 'SE'}당신이 재 할당 할 수 있습니다 x후 동안, const y = x당신이 다시 할당 할 수 y는 실수로 아래에서 변경 뭔가를 유지하기 때문이다. 즉, 자주보다 더 낫다이다. 그러나 명확하게하기 위해, 당신은 여전히 개체를 수정할 수 있습니다 y.hi = 'SO'당신이하지 않는 얼리세요.)

현실적으로 ES6 : Adopt 에 대한 인상이 맞습니다 . 사용을 중지하십시오 .letconstvar

(에서 "더 나은 부품"의 또 다른 성능 이유, 더그 말한다 ===고정보다는 추가 된 의 문제== . ==일부 "놀라운"결과를, 그래서 그냥 채택 ===.)


공개 예

Mozilla Developer Networkvar의도 한대로 작동하지 않는 예제를 제공합니다 . 그들의 예는 onclick웹 페이지에서 핸들러 를 설정하는 현실적인 예입니다 . 다음은 작은 테스트 사례입니다.

var a = [];
(function () {
   'use strict';
   for (let i = 0; i < 5; ++i) { // *** `let` works as expected ***
     a.push( function() {return i;} );
   }
} ());
console.log(a.map( function(f) {return f();} ));
// prints [0, 1, 2, 3, 4]

// Start over, but change `let` to `var`.
// prints [5, 5, 5, 5, 5]

var모든 루프 반복이 동일한 함수 범위 i변수를 공유 5하므로 루프가 끝난 후 값 을 갖기 때문에 실패합니다 .


6
그는 == 대신 === 채택에 대해 같은 대답을합니다. 후자는 깨졌지만 ES 표준위원회는 그것을 바꾸고 싶지 않았기 때문에 ===를 추가했습니다 . ==전혀 깨지지 않았습니다. 그것은 간단하게 정의 할 수 있습니다 equality comparison using coersion확인 github.com/getify/You-Dont-Know-JS/blob/master/...을
AmmarCSE

13
@AmmarCSE는 ​​암묵적인 강제에 대한 훌륭한 39 페이지의 문서입니다. 프로그래밍하는 동안 누가이 모든 것을 기억할 수 있습니까? Doug는 stackoverflow.com/a/359509/1682419에 요약 된 바와 같이 "파손"을 의미 했습니다. 즉, 값 유형이 예상 한 것보다 더 다양 할 때 쉽게 얻을 수 있습니다. 이 모든 것을 예측할 수 있습니까? [ '1.0' == 1.0, [1.0] == 1.0, [1.0] == '1.0', ['1.0'] == 1.0, [null] == '', [null] == 'null', '00' == false, [] == [], [] == 0, [] == '', [] == false, [] == true, [010] - [4] == ' 4.0 ', !![0], !![1], [0] == true, [1] == true, 1 == [[1]], 0 == [[0]], '1' == [1] ]
Jerry101

2
대부분의 예제에는 배열 피연산자가 포함되어 있습니다. toString 을 조사 할 때의 결과 와 Objects 의 구현 방식 을 이해하기 쉽습니다 . 그러나 그것이 부서진 것이 의미하는 것이라면 그것이 어디에서 왔는지 완전히 알 수 있습니다. :-)
AmmarCSE

3
const를 변경할 수 없을 때마다 const를 사용하지 않는 이유는 무엇입니까? 나는 진짜 선택의 여지가없는 사이의 의미 letvar오히려 사이에 let, var그리고const
shabunc

4
var설계된대로 작동하지만 많은 사람들이 기대하지는 않습니다. 구현 버그가 아닌 사용성 버그입니다.
Jerry101

12

올바른 코드를 작성했다면 의미 변경없이 모든 var명령문을 let명령문 으로 바꿀 수있을 것입니다 .

let식별자가 보이는 범위를 줄이므로 바람직합니다. 처음 사용하는 사이트에서 변수를 안전하게 선언 할 수 있습니다.

const보다 바람직하다 let. 참조를 변경하지 않으면 const선언을 사용하십시오 . 이는 let단일화 된 변수의 존재를 줄이고 코드를 일반적으로 쉽게 추론 할 수 있는 이점과 함께 모든 이점이 있습니다. 참조를 변경해야하는지 확실하지 않은 경우 const명시 적으로 변경해야 할 필요가 있을 때까지 참조를 선언하십시오 .


5

나는 반드시 당신이 틀렸다고 생각하지는 않지만 var를 사용하는 데주의해야 할 점이 있습니다. 본질적으로 let개발자가 특히 이름 충돌로 JavaScript의 어리 석음을 극복하는 데 도움이됩니다. var닫기 함수 범위로 가고 싶기 때문에 더 큰 범위를 갖는 것 같습니다. 함수 내부의 블록 범위 내에서 임시 변수를 사용할 수 있어야하는 것처럼 var가 필요할 때가 있습니다. 그렇지 않으면 letvar 보다 선호 하면 개발자가 이름 충돌에 도움이됩니다. 간단히 말해 ES6가 소개 한 시간입니다 let.


3
var블록 의 온도 는 블록 범위가 아닌 전체 기능 내에서 사용할 수 있습니다. 오해의 소지가있는 기능입니다.
Jerry101

1

es6에서는 "let"만 사용해야한다는 데 동의합니다. AFIK에서는 "let"을 다시 선언하면 오류가 발생하지만 (var)는 단순히 값을 무시합니다 (es5의 "strict mode"도 마찬가지입니다).


-4

let"변수를 동일하게 함"을 의미합니다. 즉 선언 및 초기화입니다.

const물론 "일정한"을 의미하는 것과는 대조적으로 존재 합니다. 이는 변수의 반대입니다.

일부 다른 언어는 객체를 선언 할 때 객체 대신 실제 객체에 접두사를 사용합니다 (예 : def"define function"의 줄임말입니다. "def"라는 요점을 완전히 누락했습니다.

Let 이 의미 불일치가 Javascript에 추가됩니다.

논리적으로, "let"키워드의 작업은 메모리를 할당하는 것이기 때문에 상수도 같은 것을 허용 할 수 있습니다.

var키워드가 const지원 되기 전에 소개 되었기 때문에 문제가 발생 하므로 이전 버전과의 호환성에 따라 var변수를 의미하지는 않습니다. 상수 값을 할당하는 데 사용될 수도 있습니다.

따라서 let잘못된 입장에서 의 소개 . 어휘 적으로, 이것이 잘못되었다는 것을 기억하기 위해, 그들은 letvs 의 어휘 범위를 변경하기로 결정 var했기 때문에 디버깅 할 때 일관성이 가장 중요합니다.

다시 말해, let사람들 (언어 관리자를 의미)은 자바 스크립트가 너무 일관성이 있고 모든 관용구와 관용구를 완전히 익히고 더 많은 것을 원한다고 생각했기 때문에 존재합니다.

참고로, var블록을 클로저로 취급하려는 경우 ( var블록을 클로저로 처리하기 전에 도입되었으므로) "화살표"블록에서는 작동하지 않지만, "화살표"블록 에서는 let작동하지 않습니다.


6
-1 : 맹렬하고 도움이되지 않으며 주로 의견에 근거합니다.
Joel Mueller

fijiaaron는 우리와 함께 농담입니다.
Jerry101

나는 어휘 형식에 대해 당신이 싫어하는 것에 동정적입니다. let왜냐하면 그것은 JavaScript에서 같은 카테고리에있는 다른 키워드의 어조와 상충되기 때문입니다. 여전히 이것은 질문에 대한 답이 아니며, 특히 잘 설명되어 있지 않습니다. 하향식
Aluan Haddad

3
let더 복잡한 것을 원하는 개발자 만이 아닙니다. vars를 반복하여 닫을 때 클로저는 var의 마지막 값을 유지하지만 오버 오버를 동일하게 수행하면 루프의 각 클로저에는 let, a, la 위의 @ Jerry101에 의한 예
TKoL
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.