이 글은 주로 ES6 연구 노트에서 블록 수준 범위 바인딩에 대한 심층적인 이해를 소개합니다. 관심 있는 친구들이 참고할 수 있습니다.
우리 모두 알다시피, js의 var 선언에는 가변 승격 메커니즘이 있습니다. 따라서 ESMAScript 6에서는 변수의 수명 주기에 대한 제어를 강화하기 위해 블록 수준 범위를 도입했습니다.
let const 선언은 여러 가지 주의할 사항이 있습니다
1. 범위가 이미 식별자가 있습니다(식별자가 var 선언이나 let 또는 const 변수를 통해 선언되었는지 여부). 이때 let 또는 const 키를 사용하여 선언을 정의하면 오류가 발생합니다
var count=10 let count=20// 此处则会抛出错误,因为同一作用域内不能重复声明
현재 범위가 다른 범위에 포함되어 있으면 let을 사용하여 포함된 범위에 동일한 이름의 변수를 선언할 수 있습니다
var count=10 if(true){ let count=20 }
2. const로 선언된 상수는 초기화되어야 합니다
다음과 같이 선언되면 , 오류가 보고됩니다
const name;//语法错误,常量未初始化
3. const로 정의된 상수에는 값을 할당할 수 없습니다. 실제 본질은 const 선언이 바인딩 수정을 허용하지 않지만 값 수정은 허용한다는 것입니다. 즉, 객체의 const 선언 후 객체의 속성 값을 수정할 수 있습니다)
const person={ name:'angela' } //可以修改对象属性的值 person.name='yun' // 修改绑定则会抛出语法错误 person={ 'name':'Shining' }
4. Temporal Dead Zone(Temporal Dead Zone)
JavaScript 엔진이 코드를 스캔할 때 변수 선언을 찾으면 이를 범위의 맨 위로 올리거나(var 선언이 있는 경우) 선언을 TDZ에 넣습니다(let 및 const 선언이 있는 경우). TDZ의 변수에 액세스하면 런타임 오류만 발생합니다. 변수 선언문이 실행된 후 해당 변수는 TDZ 밖으로 이동되어 정상적으로 접근할 수 있습니다
다음 코드는 if 블록 수준 범위에 있습니다. 과거에는 console.log가 실행될 때 값이 이미 TDZ에 있었습니다. , typeof는 상대적으로 오류가 발생하기 쉬운 연산자이지만 실제로 엔진이 오류를 발생시키는 것을 방지할 수는 없습니다
선언 전에 블록 수준 바인딩에 액세스하면 오류가 발생합니다. 임시 데드 존
if (true) { console.log(typeof value)//引用错误 let value = 'blue' }
에 있는 바인딩이기 때문입니다. 그리고 let으로 선언된 범위 밖의 변수에 typeof를 사용하면 오류가 보고되지 않습니다
console.log(typeof value) if (true) { let value = 'blue' }
5. 루프 이전에 블록 수준 범위 바인딩
함수를 만드는 것은 말로 표현할 수 없습니다
var funcs = [] for (var i = 0; i < 10; i++) { funcs.push(function () { console.log(i) }) } funcs.forEach(function (func) { func() })
루프 내부에서 생성된 모든 함수는 동일한 변수에 대한 참조를 유지하므로 루프가 끝날 때 변수 i의 값은 10이므로 결과는 10번 10으로 출력됩니다.
그래서 여러분 모두 즉시 호출 함수 표현식은 1, 2, 3...
var funcs = [] for (var i = 0; i < 10; i++) { funcs.push((function (value) { return function () { console.log(value) } })(i)) } funcs.forEach(function (func) { func() })
let을 사용하면 즉시 호출 함수 표현식을 단순화할 수 있습니다. 실제로 각 반복 루프는 새 변수를 생성하고 이전 반복에서 동일한 이름을 가진 변수 값으로 초기화합니다
var funcs = [] for (let i = 0; i < 10; i++) { //其实是每次循环的时候let声明都会创建一个新变量i并将其初始化为i的当前值,所以在循环内部创建的每个函数都能得到属于它们自己的i的副本 funcs.push(function () { console.log(i) }) } funcs.forEach(function (func) { func()//这里输出是0 然后是1、2....9 })
이 기능은 for in에도 적용됩니다. 예를 들어
var funcs = [], obj = { a: true, b: true, c: true } for (let key in obj) { funcs.push(function () { console.log(key) }) } funcs.forEach(function (func) { func()//输出的是a b c })
6 , let 선언 루프의 기능은 const 선언에도 적용됩니다. 유일한 차이점은 const가 바인딩을 변경할 수 없다는 것입니다.
위의 예에서 let을 const로 변경하면 b c
var funcs = [], obj = { a: true, b: true, c: true } //之所以可以运用for in 和for of循环中,是因为每次迭代不会修改已有绑定,而是会创建一个新绑定 for (const key in obj) { funcs.push(function () { console.log(key)// 同样输出a b c 唯一的区别是循环内不能更改key的值 }) } funcs.forEach(function (func) { func() })
다음 예에서는 오류가 발생합니다. for 루프에서 i의 바인딩이 변경되고 const 상수가 바인딩을 변경할 수 없기 때문에 보고되었습니다.
var funcs = [] for (const i = 0; i < 10; i++) { funcs.push(function () { console.log(i) }) } funcs.forEach(function (func) { func() })
7. 전역 범위 바인딩
var이 전역 범위에 적용되면 새 전역 변수는 전역 개체(브라우저 환경의 창 개체)의 속성에 영향을 미칩니다. 즉, var를 사용하면 기존 전역 변수를 실수로 덮어쓸 가능성이 높습니다
위 코드에서 볼 수 있듯이 전역 개체도 RegExp 배열이 덮어쓰여집니다
그러나 let 또는 const는 전역 범위에서 새 바인딩을 생성하지만 바인딩은 전역 개체의 속성으로 추가되지 않습니다. 즉, let 또는 const는 전역 변수를 재정의할 수 없습니다. , 그러나 그림자만 가능합니다
RegExp와 window.RegExp는 현재 다릅니다
let RegExp='hello' console.log(RegExp) //hello console.log(window.RegExp===RegExp)//false const ncz='hi' console.log(ncz) console.log("ncz" in window)
모범 사례:
기본적으로 var 대신 let을 사용하세요
Default const 및 only 사용 변수 값을 정말로 변경해야 할 때 let을 사용하세요
위 내용은 JavaScript ES6의 블록 수준 범위 바인딩의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!