ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript ES6 のブロックレベルのスコープ バインディング

JavaScript ES6 のブロックレベルのスコープ バインディング

巴扎黑
巴扎黑オリジナル
2017-08-21 09:39:181199ブラウズ

この記事は主に ES6 の学習ノートでブロックレベルのスコープ バインディングについて詳しく紹介しています。興味のある方は参考にしてください。 , そこで、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. 時間的デッドゾーン


JavaScript エンジンがコードをスキャンして変数宣言を見つけると、それらをスコープの先頭に上げるか (var 宣言に遭遇した場合)、宣言を TDZ に配置します (let および const 宣言に遭遇した場合)。TDZ 内の変数にアクセスすると、変数宣言ステートメントが実行された後でのみ実行時エラーが発生します。実行すると、変数は TDZ の外に移動され、正常にアクセスできるようになります 以下のコードは if ブロックレベルのスコープにあります。 console.log が実行されると、値はすでに TDZ にあります。 以前は、typeof は比較的エラーでした。 -prone 演算子ですが、実際にはエンジンがエラーをスローするのを防ぐことはできませんでした

バインディングが一時的なデッドゾーンにあり



if (true) {
 console.log(typeof value)//引用错误
 let value = 'blue'
}

し、変数に typeof を使用しているため、宣言前にブロックレベルのバインディングにアクセスするとエラーが発生します


let で宣言されたスコープの外ではエラーは報告されません

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 回出力されます


。つまり、ループ内で即時呼び出し関数式が強制的に使用されます。 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()
})

となるように生成されるカウンタ変数のコピー前の反復で同じ名前の変数の値を使用します

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 に変更すると a 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()
})

次の例では、i のバインドが変更されているため、エラーが報告されますfor ループ内で変更され、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 Array も上書きされます


しかし、let または const はグローバル スコープに新しいバインディングを作成しますが、バインディングはグローバル オブジェクトのプロパティとして追加されません。つまり、let または const はグローバル変数をオーバーライドできず、シェーディングすることしかできません。

現時点での RegExp と window.RegExp は異なります

let RegExp=&#39;hello&#39;
console.log(RegExp) //hello
console.log(window.RegExp===RegExp)//false

const ncz=&#39;hi&#39;
console.log(ncz)
console.log("ncz" in window)

ベストプラクティス:


デフォルトでは var の代わりに let を使用してください


デフォルトでは const を使用し、本当に必要な場合にのみ let を使用してください変数の値を変更するには

以上がJavaScript ES6 のブロックレベルのスコープ バインディングの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。