>  기사  >  웹 프론트엔드  >  es6 블록 수준 바인딩의 let 및 const에 대한 자세한 분석

es6 블록 수준 바인딩의 let 및 const에 대한 자세한 분석

不言
不言앞으로
2019-03-30 09:43:182511검색

이 기사는 es6 블록 수준 바인딩의 let 및 const에 대한 자세한 분석을 제공합니다. 필요한 친구가 참고할 수 있기를 바랍니다.

변수 선언은 항상 js 작업에서 가장 미묘한 부분이었습니다. C 언어와 달리 변수는 항상 생성될 때 선언됩니다. js 언어에서는 명령문을 작성해야 할 때 변수를 선언할 수 있습니다.

var let const 변수 선언

var 선언 및 변수 승격.

var 키워드를 사용하여 변수를 선언하면 변수가 어디에 선언되든 함수 상단에 선언됩니다. (함수 내에 없으면 선언한 것으로 간주됩니다.) 함수의 최상위에 있어야 함) 전역 범위의 최상위) 이를 변수 호이스팅이라고 합니다.

var은 다음과 같이 호이스팅됩니다.

function getValue(condition) {
if (condition) {
var value = "blue";
// 其他代码
return value;
} else {
// value 在此处可访问,值为 undefined
return null;
}
// value 在此处可访问,值为 undefined
}

블록 수준 선언 let# 🎜🎜#

block-level 선언은 선언된 변수가 지정된 범위 외부에 접근할 수 없음을 의미합니다. 블록 수준 범위는 다음과 같은 상황에서 생성됩니다.

    함수 내부에서,
  1. # 🎜🎜#코드 블록 내부(중괄호 한 쌍으로 묶음)
  2. let 선언 구문은 var 선언 이후 구문과 동일합니다. 변수를 함수의 맨 위로 승격시키지 않으므로 전체 코드 블록 내에서 변수를 사용할 수 있도록 수동으로 맨 위에 let 선언을 배치해야 합니다.

아래와 같이:

function getValue(condition) {
if (condition) {
let value = "blue";
// 其他代码
return value;
} else {
// value 在此处不可用
return null;
}
// value 在此处不可用
}

중복 식별은 금지됩니다

코드 내에 식별자가 정의된 경우 반복된 let 문은 오류를 보고합니다. # 🎜🎜#
var a = 30;
//报错
let a = 30;

a 변수는 두 번 선언됩니다. 한 번은 var를 사용하고 다른 한 번은 let을 사용합니다. let은 동일한 범위에서 기존 식별자를 다시 선언할 수 없기 때문에 여기에서 let을 선언하면 오류가 발생합니다. 반면, 중첩된 범위에서 동일한 이름을 가진 새 변수를 선언하기 위해 let을 사용하면 오류가 발생하지 않습니다. 다음 코드는 이를 보여줍니다.

var count = 30;
// 不会抛出错误
if (condition) {
let count = 40;
// 其他代码
}
이 코드에서는 오류가 발생하지 않습니다. , 핵심은

let이 동일한 레벨 코드 블록에서 선언을 반복하면 오류를 보고한다는 것입니다. es6의 const 구문 명령문을 작성하세요. const를 사용하여 선언된 변수는 상수로 간주됩니다. 즉, 해당 값은 설정된 후에 변경할 수 없습니다. 이로 인해 모든 const 변수는 선언 시 초기화되어야 합니다.

// 有效的常量
const maxItems = 30;
// 语法错误:未进行初始化
const name;

maxItems 변수는 초기화되므로 해당 const 선언이 정상적으로 작동할 수 있습니다. name 변수가 초기화되지 않아 이 코드를 실행하려고 하면 오류가 발생합니다. const 선언은 변수 바인딩과 자체 생성 값의 수정을 방지합니다. 즉, const 선언은 변수 멤버의 수정을 방지하지 않습니다. 예:
const person = {
name: "Nicholas"
};
// 工作正常
person.name = "Greg";
// 抛出错误
person = {
name: "Greg"
};
const 선언과 let 선언의 비교

우선, 모두 블록 수준 선언이므로 다음을 의미합니다. 상수는 선언문 블록 외부에서 액세스할 수 없으며 선언은 승격되지 않습니다.

if (condition) {
const maxItems = 5;
// 其他代码
}
// maxItems 在此处无法访问

#🎜 🎜#같은 레벨에 있습니다. 범위 내에서 반복적으로 선언하면 오류가 발생합니다.
  1. 임시 데드 존
사용할 때 선언에 let 또는 const를 사용하면 선언에 도달할 때까지 액세스할 수 없으며 액세스하려고 하면 참조 오류가 발생합니다. 이 문제는 임시 데드존 때문에 발생합니다
  1. JS 엔진이 다음 코드 블록을 살펴보고 변수 선언을 찾으면 선언을 var의 경우 함수 또는 전역 역할로 승격합니다. 도메인의 상단은 let 또는 const를 향하고 있는 동안 임시 데드존에 선언을 배치합니다. 임시 데드존 내의 변수에 액세스하려고 하면 "런타임" 오류가 발생합니다. 변수 선언문을 실행해야만 해당 변수가 임시 데드존에서 제거되어 안전하게 사용할 수 있습니다.

    루프의 블록 수준 바인딩
  2. for (var i = 0; i < 10; i++) {
    process(items[i]);
    }
    // i 在此处仍然可被访问
    console.log(i); // 10
출력 결과는 예상 값이 아니라 10입니다. 이는 var 선언으로 인한 변수 승격 때문입니다. 똑똑하다면 블록 수준 바인딩을 사용하여 변수를 선언하는 것을 분명히 생각할 것입니다.

for (let i = 0; i < 10; i++) {
process(items[i]);
}

console.log(i);

i 여기서 출력이 정상일까요? 실제로 이 예에서는 오류가 발생합니다. 왜? 왜냐하면 나는 여기에 접근할 수 없기 때문이다. 이 예제의 변수 i는 for 루프 내에서만 사용할 수 있으며 루프가 끝나면 어디에서도 액세스할 수 없습니다.

코드를 살펴보겠습니다

var funcs = [];
for (var i = 0; i < 10; i++) {
funcs.push(function() { console.log(i); });
}
funcs.forEach(function(func) {
func(); // 输出数值 "10" 十次
});

이 코드는 0부터 9까지의 값을 출력할 것이라고 예상하셨겠지만, 같은 줄에 값 10을 출력합니다. . 이는 변수 i가 루프의 각 반복에서 공유되기 때문입니다. 즉, 루프 내에서 생성된 함수는 모두 동일한 변수에 대한 참조를 갖습니다. 루프가 끝나면 변수 i의 값은 10이 되므로 console.log(i)가 호출되면

은 매번 10을 인쇄합니다.

이 문제를 해결하기 위해 개발자는 아래와 같이 루프 내에서 IIFE(즉시 호출 함수 표현식)를 사용하여 각 반복마다 변수의 새 복사본을 강제로 생성합니다.

var funcs = [];
for (var i = 0; i < 10; i++) {
funcs.push((function(value) {
return function() {
console.log(value);
}
}(i)));
}
funcs.forEach(function(func) {
func(); // 从 0 到 9 依次输出
});
#🎜 🎜#let 문 내부 루프

let 문은 위 예에서 IIFE의 효과를 효과적으로 모방하여 루프를 단순화합니다. 반복할 때마다 동일한 이름을 가진 새로운

변수가 생성되고 초기화됩니다. 이는 IIFE를 완전히 생략하고 다음과 같이 원하는 결과를 얻을 수 있음을 의미합니다.

var funcs = [];
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i);
});
}
funcs.forEach(function(func) {
func(); // 从 0 到 9 依次输出
})

我们是否会想到这个问题:为什么同样的代码使用let声明会导致不一样的结果呢?
在循环中let声明每次都创建了一个新的i变量,因此在循环内部创建的函数获得了各自的i副本,而每个i副本的值都会在每次的循环迭代声明变量的时候确定了

var funcs = [],
object = {
a: true,
b: true,
c: true
};
for (let key in object) {
funcs.push(function() {
console.log(key);
});
}
funcs.forEach(function(func) {
func(); // 依次输出 "a"、 "b"、 "c"
});

本例中的 for-in 循环体现出了与 for 循环相同的行为。每次循环,一个新的 key 变量绑定就被创建,因此每个函数都能够拥有它自身的 key 变量副本,结果每个函数都输出了一个不同的值。而如果使用 var 来声明 key ,则所有函数都只会输出 "c" 。
let 声明在循环内部的行为是在规范中特别定义的,而与不提升变量声明的特征没有必然联系。事实上,在早期 let 的实现中并没有这种行为,它是后来才添加的。

循环内的常量声明

虽然es6没有明确的规范我们不能在for循环中使用const声明,然而它会根据循环方式的不同而有不同的行为,我们可以在初始化时使用const,但是当循环试图改变变量的值的时候会抛出错误,例如:

var funcs = [];
// 在一次迭代后抛出错误
for (const i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i);
});
}

在此代码中, i 被声明为一个常量。循环的第一次迭代成功执行,此时 i 的值为 0 。在
i++ 执行时,一个错误会被抛出,因为该语句试图更改常量的值。因此,在循环中你只能使
用 const 来声明一个不会被更改的变量
而另一方面, const 变量在 for-in 或 for-of 循环中使用时,与 let 变量效果相同。因
此下面代码不会导致出错:

var funcs = [],
object = {
a: true,
b: true,
c: true
};
// 不会导致错误
for (const key in object) {
funcs.push(function() {
console.log(key);
});
}
funcs.forEach(function(func) {
func(); // 依次输出 "a"、 "b"、 "c"
});

这段代码与“循环内的 let 声明”小节的第二个例子几乎完全一样,唯一的区别是 key 的值在
循环内不能被更改。 const 能够在 for-in 与 for-of 循环内工作,是因为循环为每次迭
代创建了一个新的变量绑定,而不是试图去修改已绑定的变量的值(就像使用了 for 而不是
for-in 的上个例子那样)。

全局块级绑定

let 与 const 不同于 var 的另一个方面是在全局作用域上的表现。当在全局作用域上使用 var 时,它会创建一个新的全局变量,并成为全局对象(在浏览器中是 window )的一
个属性。

总结

let和const块级作用域的引入,能够使我们减少很多无心的错误,它们的一个副作用,是不能在变量声明位置之前访问它们

块级绑定当前的最佳实践就是:在默认情况下使用 const ,而只在你知道变量值需要被更改的情况下才使用 let 。这在代码中能确保基本层次的不可变性,有助于防止某些类型的错误。

本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的JavaScript视频教程栏目!

위 내용은 es6 블록 수준 바인딩의 let 및 const에 대한 자세한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제