es6塊級繫結筆記

suydCao發表於2018-12-20

作用域

作用域:程式語言最基本的功能就是儲存和訪問變數的值,如何對變數儲存/訪問的某種良好的規則,就是作用域。作用域負責收集並維護由所有宣告的標示符(變數)組成的一系列查詢,並實施一套非常嚴格的規則,確定當前執行的程式碼對這些識別符號的訪問許可權。

作用域是根據名稱查詢變數的一套規則。當一個塊或者函式巢狀在另外一個塊或者函式中時,就發生了作用域巢狀。

詞法作用域:定義在詞法階段的作用域。詞法作用域是你在寫程式碼時將變數和塊作用域寫在哪裡來決定的,因此詞法分析器處理程式碼時保持作用域不變。

函式作用域:每宣告一個函式都會為自身建立一個作用域,屬於這個函式的全部變數都可以在這個函式範圍內使用/複用。一段程式碼我們可以在它的外部新增一個包裝函式,這樣就可以將內部的變數和函式定義隱藏(這種方法可以有效解決變數或者函式汙染外部作用域,閉包和函式自呼叫也是這種方法的延伸)。外部作用域無法訪問包裝函式內部的任何內容。

宣告提升

es5及之前只有函式作用域和全域性作用域同時也只有兩種變數宣告,var 和function。 使用函式及變數的宣告都將被提升到當前作用域的最頂部。

1.變數提升(var的起作用,只有宣告提升,初始化不會):
var a =3;
function b( ) {
    //實際上var了的變數提升到了函式內部的頂部
    console.log( a );
    var a=4;			
}
b( ); // undefind
實際執行
var a =3;
function b( ) {
    var a ; //var a 宣告!提升到此,並值為undefined
    console.log( a );
    a=4; // 初始化			
}
b();
2.函式提升(函式宣告起作用):
函式提升是把整個函式都提到前面去。 
function f( ) { 
    console.log('I am outside!'); 
}
( function ( ) {		
    if ( false ) {
        // 重複宣告一次函式f
        function f( ) {
            console.log( 'I am inside!' );
        }
    }
    f( );
}( ) );//輸出'I am inside!'
實際執行:
function f( ) { console.log( 'I am outside!' ); }
( function ( ) {	
    function f( ) { console.log( 'I am inside!' );	}
    if ( false ) {
    // 重複宣告一次函式f
    }
    f( );
}( ) );
3.全域性作用域的會被後面提升上來的覆蓋( var的變數為undefined ), 區域性作用域的會提升到函式內部的頂部;變數只有var的會提升,函式只有函式宣告會提升;
4:函式宣告和函式表示式
function a( ){ } //函式宣告  會提升
所以 :
a( );
function a ( ){ }  //正確
var b = function ( ) { } //函式表示式 不會提升
所以:
b( );
var b = function ( ) { } //錯誤
複製程式碼

塊級宣告

es6引入了塊級作用域,並新增了四種宣告let/const/import/class。

 
1.// 只在當前作用域內可以訪問
{
    let a = 10;
    var b = 1;
}
b // 1
a // ReferenceError: a is not defined.

2.// 同一作用域裡不允許重複宣告

let a = 'aaa';
let a = 'bbb'; //報錯 :語法錯誤

let a = 'aaa';
{let a = 'bbb';} // 不會報錯

3.// 不會變數提升

console.log(a); // 報錯
let a; 

4.//暫時性死區 TDZ
var a =1;
{
	let a = 3;
}
// 報錯 :引用錯誤

5.//全域性宣告不會賦值到window物件

window.d = 123
let d = 234
console.log(d); // 234


2.let/const/import/class也遵守上述規則。
3.const是常量,不可再次被賦值(只限於棧記憶體裡資料,棧記憶體放的基本資料型別和引用型別的地址不可變)

複製程式碼

迴圈中使用

1.let
for(let i =0; i<10; i++){
 let i = 123;
 setTimeout(
	()=>{console.log(i);},
 1000);
}
// 30786
// 123
console.log(i) // ReferenceError: i is not defined

for(var i =0; i<10; i++){
 setTimeout(
	()=>  {console.log(i);},
  1000);
}
// 51
// 10

for(let i =0; i<10; i++){
 setTimeout(
	()=>  {console.log(i);},
  1000);
}
// 0 1 2 3 4 5 6 7 8 9

2.const
const 在for迴圈中迴圈一次後會報錯,因為i++會修改值;
在for infor of中則可以正常使用,因為每次迴圈會建立一個常量。

// 51
// 10
複製程式碼

相關文章