ES6學習筆記之變量聲明let,const


最近用淘寶的weex做了個項目,最近稍微閑下來了。正好很久沒有接觸RN了,所以趁這個機會系統的學習一下ES6的相關知識。

孔子說:沒有對比就沒有傷害。所以我們要拿ES6和ES5好好對比的學習。這樣才能明白es6是多少的好,積極的擁抱她!

1.let

用let聲明的變量,只會在let命令所在的代碼塊內有效。

let的塊狀作用域

我們來看一個簡單的例子:

'use strict';
{
    let name = 'cloud';
    var age = 21;
}
name;//ReferenceError: name is not defined
age;//21

我們在let聲明變量name的代碼塊之外去訪問這個變量,結果name是沒有定義的。如果我們希望在能訪問到name應該怎么做呢?

'use strict';
{
    let name = 'cloud';
    var age = 21;
    name;//cloud
}

沒錯,我們在let聲明變量的代碼塊中去訪問name變量。結果也正如我們期望的那樣,name的值被訪問到了。對於高級oo語言而言,他們都是基於塊狀作用域的。

所以說,let讓我們聲明的變量也擁有了塊狀作用域這樣一個概念,而不僅僅是函數作用域了。

既然有了塊級作用域,那把let用來聲明循環里的變量是極好的。

'use strict';
//死循環
for(var i = 0; i < 5; i++){
    console.log(i);
    for(var i = 0; i < 3; i++){
        console.log(i);
    }
}

for(let i = 0; i < 5; i++){
    console.log(i);
    for(let i = 0; i < 3; i++){
        console.log(i);
    }
}

如果沒有let的話,上面代碼中的內循環每次都會把var聲明的變量i重置為0,所以毫無疑問,這是一個死循環。所以我們必須把內循環中變量i換成變量j,或者其他的名稱。但是這也會帶來一個副作用,就是循環完成以后的i,被泄露成了全局變量。

'use strict';
for(var i = 0; i < 5; i++){
    i;//0,1,2,3,4
}
i;//5
for(let i = 0; i < 5; i++){
    i;//0,1,2,3,4
}
i;//ReferenceError: i is not defined

 

let聲明的變量不存在變量聲明提升

'use strict';
name; //undefined
age; //ReferenceError: age is not defined
var name = 'cloud';
let age = 21;

用var聲明的變量name,雖然我們在name使用后才聲明並給其賦值,但是因為變量聲明提升的原因,我們看到name已經聲明了,只是其值是undefined而已。但是用let聲明的age變量,卻沒有定義。所以說let是不存在變量聲明提升的。

let的暫時性死區(temporal dead zone,簡稱TDZ)

只要是塊級作用域中存在let命令,它所在的區域就成為了暫時性死區,使用let命令聲明變量之前,該變量都是不可用的。同時該變量不再受到外部的影響。

var name = 'new cloud';
{
//TDZ start name = 'cloud'; name;//ReferenceError: name is not defined let name;    //TDZ end name;//undefined let name = 'cloud'; name;//cloud }

如上代碼,在let聲明name之前,那么這個變量都是不可用的。所以這也帶來一個問題,當我們使用typeof這樣的反射機制來檢測我們的所需的變量是否按照我們設想的那樣,typeof不再是一個堅定不移的忠臣了,它也會報錯了。

{
    typeof name;//undefined
    var name = 'cloud';
    typeof name;//ReferenceError: name is not defined
    let name = 'cloud';
}

let塊狀作用域內聲明的變量,不允許重復聲明。

1.
'
use strict'; var name = 'cloud'; var name = 'new cloud'; name;//new cloud
2.
'
use strict'; { let name = 'cloud'; var name = 'new cloud'; name; let name = 'cloud'; var name = 'new cloud'; name; let name = 'cloud'; let name = 'new cloud'; name; //SyntaxError: Identifier 'name' has already been declared }

第二段代碼中的所有聲明方式,都會報錯。name已經被聲明。

'use strict';
function setName(name){
    let name = name;//SyntaxError: Identifier 'name' has already been declared
    {
        let name = 'new cloud';
        console.log(name);//new cloud
    }
    console.log(name);//cloud
}
setName('cloud');

同樣,在函數中重新聲明變量也會報錯的。

2.const

const是一個只讀的常量。一旦聲明,就不可更改。

'use strict';
const PI = 3.14;
PI = 3.1415;//TypeError: Assignment to constant variable

如果用const聲明了常量,但是並沒有去初始化它。那么,也是會報錯的。

'use strict';
const PI;//SyntaxError: Missing initializer in const declaration

同樣,const的作用域與let命令相同:只在聲明所在的塊級作用域內有效。const命令聲明的常量也是不提升,同樣存在暫時性死區,只能在聲明的位置后面使用。const聲明的常量,也與let一樣不可重復聲明。

如果我們用const來聲明一個引用類型的話。const只能保證指針域不變,但是並不能保證數據域是不可變更的。

'use strict';
const employee = {};
employee['name'] = 'cloud';
employee['age'] = 21;

employee = {}; //TypeError: "employee " is read-only
employee['name'] = 'new cloud';
console.log(employee.name);//new cloud

如果想把一個對象完成的凍結的話,應該是用Object.freeze()方法。

const employee = Object.freeze({});
employee.name= 'cloud';//TypeError: Can't add property prop, object is not extensible

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM