"let"및 "var"사용의 차이점은 무엇입니까?
질문
ECMAScript 6은 합자 진술을 도입했습니다.
나는 그것이 로컬 변수로 묘사되었음을 들었지만, 나는 그것이 VAR 키워드와 어떻게 다르게 행동하는지 확신하지 못합니다.
차이점은 무엇입니까?VAR 대신 사용할 수있는 경우는 언제입니까?
답변
범위 규칙
주요 차이점은 범위 규칙입니다.VAR 키워드로 선언 된 변수는 {} (따라서 블록 범위)로 표시된 즉석 둘레 블록으로 변수가 범위가 확대되는 동안 VAR 키워드 (따라서 함수 범위)로 범위가 지정됩니다.
함수 실행 () { var foo = "foo"; bar = "bar"를합시다; console.log (foo, bar);// foo bar. { var moo = "mooo" baz = "bazz"를 봅시다; console.log (Moo, Baz);// Mooo Bazz. } console.log (moo);// mooo. console.log (BAZ);// ReferenceError. } 운영();
왜 키워드가 언어에 도입 된 이유는 기능 범위가 혼란스러워하고 JavaScript의 버그의 주요 버그 중 하나였습니다.
다른 스택 오버플로 질문 에서이 예제를 살펴보십시오.
var funcs = []; // 3 가지 기능을 만드겠습니다 for (var i = 0; i <3; i ++) { // 그리고 그들을 funcs에 보관하십시오 Funcs [i] = function () { // 각각은 값을 기록해야합니다. console.log ( "내 가치 :"+ i); }; } for (var j = 0; j <3; j ++) { // 이제는 각각을 볼 수 있도록 실행합시다. Funcs [j] (); }
내 가치 : 3 시간을 펀치 [j] ()를 할 때마다 3을 콘솔로 출력했습니다.익명의 기능이 동일한 변수에 묶여 있기 때문에 호출되었습니다.
사람들은 루프에서 올바른 값을 캡처하는 데 즉시 호출 된 기능을 만들어야했습니다.
호이 스팅
var 키워드로 선언 된 변수는 호이스트 (코드가 실행되기 전에 정의되지 않음)가 호스팅됩니다. 이는 둘러싸는 이전에도 포함 된 범위에서 액세스 할 수 있음을 의미합니다.
함수 실행 () { console.log (foo);// 한정되지 않은 var foo = "foo"; console.log (foo);// foo. } 운영();
정의가 평가 될 때까지 변수가 초기화되지 않도록하십시오.초기화가 referenceError에서 초기화되기 전에이를 액세스합니다.변수는 초기화가 처리 될 때까지 블록의 시작으로부터의 "시간적 사탈 영역"이라고한다.
함수 체크 쇼스트 () { console.log (foo);// ReferenceError. foo = "foo"합시다; console.log (foo);// foo. } 체크 쇼핑 ();
글로벌 오브젝트 속성 만들기
최상위 수준에서 var와 달리 전역 개체에 속성을 만들지 않습니다.
var foo = "foo";// 전 세계적으로 범위 bar = "bar"를합시다;// 전역으로 범위가 없을 수 없습니다 console.log (window.foo);// foo. console.log (window.bar);// 한정되지 않은
redeclaration.
엄격한 모드에서 VAR은 SyntaxError를 올리면 동일한 범위에서 동일한 변수를 다시 선언 할 수 있습니다.
'엄격한 사용'; var foo = "foo1"; var foo = "foo2";// 아무런 문제 없음, 'foo1'은 'foo2'로 대체됩니다. bar = "bar1"을합시다; bar = "bar2"를합시다;// syntaxerror : 식별자 'bar'가 이미 선언되었습니다.
답변
폐쇄에 문제를 피하기 위해 사용할 수도 있습니다.아래의 예와 같이 오래된 참조를 유지하는 대신 신선한 가치를 묶습니다.
for (var i = 1; i <6; i ++) { $ ( "div"+ i) .click (함수 () {console.log (i);}); } <스크립트 src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"> script>
각 숫자를 클릭하면 콘솔에 로그인합니다. p>
위의 코드는 고전적인 JavaScript 클로저 문제를 보여줍니다.i 변수에 대한 참조는 i의 실제 값이 아닌 클릭 핸들러 폐쇄에 저장됩니다.
한 번의 클릭 핸들러는 6 개를 보유하고 있으므로 각 클릭으로 6을 두드리는 카운터 객체가 하나만 있으므로 동일한 객체를 참조합니다.
일반적인 해결 방법은 익명의 함수에서 이것을 포장하고 i를 인수로 전달하는 것입니다.이러한 문제는 아래의 코드와 같이 var var var var를 사용하여 이제 피할 수 있습니다.
(크롬 및 Firefox 50에서 테스트 됨)
for (i = 1, i <6; ++) { $ ( "div"+ i) .click (함수 () {console.log (i);}); } <스크립트 src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"> script>
각 숫자를 클릭하면 콘솔에 로그인합니다. p>
답변
let와 var의 차이점은 무엇입니까?
var 문을 사용하여 정의 된 변수는 함수의 시작 부분에서 정의 된 함수 전체에서 알려져 있습니다.(*) let 문을 사용하여 정의 된 변수는 이웃이 정의 된 순간부터 정의 된 블록에서만 알려져 있습니다.(**)
차이점을 이해하려면 다음 코드를 고려하십시오.
// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here
function loop(arr) {
// i IS known here, but undefined
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( var i = 0; i < arr.length; i++ ) {
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( let j = 0; j < arr.length; j++ ) {
// i IS known here, and has a value
// j IS known here, and has a value
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
}
loop([1,2,3,4]);
for( var k = 0; k < arr.length; k++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
};
for( let l = 0; l < arr.length; l++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS known here, and has a value
};
loop([1,2,3,4]);
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
여기에서 우리의 변수 j가 첫 번째 루프에서만 알려져 있지만 전후에는 아닙니다.그러나 우리의 변수 i는 전체 기능으로 알려져 있습니다.
또한 블록 범위 변수가 호이스트가 없기 때문에 선언되기 전에 알 수 없음을 고려하십시오.또한 동일한 블록 내에서 동일한 블록 범위 변수를 다시 표시 할 수 없습니다.이렇게하면 블록 범위 변수가 전역 적으로 또는 기능적으로 범위가있는 변수보다 적은 오류가 발생하지 않으며 여러 선언이 발생한 경우에 오류가 발생하지 않습니다.
오늘 사용하는 것이 안전합니까?
어떤 사람들은 미래에 우리는 진술을 사용하고 var 문이 쓸모 없게 될 것입니다.JavaScript Guru Kyle Simpson은 왜 그가 사실이 아니라고 믿는 이유에 대해 매우 정교한 기사를 썼습니다.
그러나 오늘날, 그것은 확실히 그렇지 않습니다.사실, 우리는 실제로 합실 진술을 사용하는 것이 안전할지 여부를 스스로에게 물어볼 필요가 있습니다.그 질문에 대한 답변은 환경에 따라 다릅니다.
서버 측 JavaScript 코드 (node.js)를 작성하는 경우 let 문을 안전하게 사용할 수 있습니다. 클라이언트 측 JavaScript 코드를 작성하고 트래픽 또는 Babel-Standalone과 같은 브라우저 기반 트랜스 프릴 러를 사용하는 경우, let 문을 안전하게 사용할 수 있지만, 코드는 성능과 관련하여 최적이지만 코드가 최적이지만 코드가 될 수 있습니다. 클라이언트 측 JavaScript 코드를 작성하고 노드 기반 트랜스 프레임 (Traceur Shell Script 또는 Babel)을 사용하는 경우 Let Streates를 안전하게 사용할 수 있습니다.그리고 브라우저가 트랜스 레일 코드에 대해서만 알고 있기 때문에 성능 단점이 제한되어야합니다. 클라이언트 측 JavaScript 코드를 작성하고 트랜지트를 사용하지 않는 경우 브라우저 지원을 고려해야합니다. 아직도 전혀 지원하지 않는 브라우저가 있습니다.

브라우저 지원을 추적하는 방법
이 답변을 읽을 때 let 문을 지원하는 브라우저의 최신 개요는 페이지를 사용할 수 있습니다.
(*) 전 세계적으로 및 기능적으로 범위가 지정된 변수는 JavaScript 변수가 호이스트되기 때문에 선언되기 전에 초기화되어 사용될 수 있습니다.즉, 선언은 항상 범위의 맨 위에 있습니다.
(**) 블록 범위 변수가 호이스트가 아닙니다
답변
다음은 몇 가지 예제로 키워드의 설명입니다.
var와 같이 잘 작동하자.주요 차이점은 var 변수의 범위가 전체 둘러싸인 기능입니다.
Wikipedia 의이 표는 JavaScript 1.7을 지원하는 브라우저를 보여줍니다.
Mozilla와 Chrome 브라우저 만 지원합니다.즉, 사파리, 잠재적으로 다른 사람들은 그렇지 않습니다.
답변
수락 된 답변이 누락되었습니다.
{
let a = 123;
};
console.log(a); // ReferenceError: a is not defined
답변
허락하다
블록 범위
let 키워드를 사용하여 선언 된 변수는 블록 범위가 있으므로 선언 된 블록에서만 사용할 수 있음을 의미합니다.
최상위 수준 (기능 외부)
최상위 레벨에서 Variables를 사용하여 선언 된 변수는 전역 개체에 속성을 만들지 마십시오.
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined
함수 안에
함수 내부 (블록 외부)에서 var와 동일한 범위를 가지고 있습니다.
(() => {
var functionScopedVariable = 42;
let blockScopedVariable = 43;
console.log(functionScopedVariable); // 42
console.log(blockScopedVariable); // 43
})();
console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
블록 내부
블록 내부를 사용하여 선언 된 변수는 해당 블록 외부에서 액세스 할 수 없습니다.
{
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
}
console.log(globalVariable); // 42
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
루프 내부
루프를 루프로 선언 한 변수는 해당 루프 내부에서만 참조 할 수 있습니다.
for (var i = 0; i < 3; i++) {
var j = i * 2;
}
console.log(i); // 3
console.log(j); // 4
for (let k = 0; k < 3; k++) {
let l = k * 2;
}
console.log(typeof k); // undefined
console.log(typeof l); // undefined
// Trying to do console.log(k) or console.log(l) here would throw a ReferenceError.
클로저가있는 루프
루프가있는 대신 루프 대신 사용하도록 사용하는 경우 각 반복으로 새 변수를 얻습니다.즉, 루프 내부에서 폐쇄를 안전하게 사용할 수 있음을 의미합니다.
// Logs 3 thrice, not what we meant.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Logs 0, 1 and 2, as expected.
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 0);
}
임시 구역
일시적인 데드 존 때문에, 사용하자를 사용하여 선언 된 변수는 선언되기 전에 액세스 할 수 없습니다.그렇게하려고 시도하면 오류가 발생합니다.
console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;
다시 선언하지 않습니다
Helf를 사용하여 여러 번 동일한 변수를 선언 할 수 없습니다.또한 VAR을 사용하여 선언 된 다른 변수와 동일한 식별자로 사용하여 변수를 선언 할 수 없습니다.
var a;
var a; // Works fine.
let b;
let b; // SyntaxError: Identifier 'b' has already been declared
var c;
let c; // SyntaxError: Identifier 'c' has already been declared
죄송합니다
Const는 Reth-It-compoped이며 TDZ가 있습니다.그러나 다른 두 가지가 있습니다.
다시 할당 없음
const를 사용하여 선언 된 변수는 다시 할당 할 수 없습니다.
const a = 42;
a = 43; // TypeError: Assignment to constant variable.
그것이 가치가 불변하다는 것을 의미하지는 않습니다.그 속성은 여전히 변경 될 수 있습니다.
const obj = {};
obj.a = 42;
console.log(obj.a); // 42
불변의 객체를 갖고 싶다면 Object.Freeze ()를 사용해야합니다.
const obj = Object.freeze({a: 40});
obj.a = 42;
console.log(obj.a); // 40
console.log(obj.b); // undefined
이니셜 라이저가 필요합니다
const를 사용하여 변수를 선언 할 때 항상 값을 지정해야합니다.
const a; // SyntaxError: Missing initializer in const declaration
출처:https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var
최근댓글