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 Network 는 var의도 한대로 작동하지 않는 예제를 제공합니다 . 그들의 예는 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를 사용하지 않는 이유는 무엇입니까? 나는 진짜 선택의 여지가없는 사이의 의미 let와 var오히려 사이에 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.