ES6学习笔记--let和const
今天開始讀阮一峰的《ECMAScript 6 入門》,在這里記錄下閱讀過程中的要點,以便隨時查閱。
let和const
頂層對象的屬性與全局變量掛鉤,被認(rèn)為是js最大的敗筆之一,ES6開始,全局變量將逐步與頂層對象脫鉤。為了保持兼容性,一方面,var和function聲明的全局變量,依舊是頂層對象的屬性;另一方面,let,const,class命令聲明的全局變量,不屬于頂層對象的屬性:
var a = 1; window.a;//1 let b = 2; window.b;//undefinedconst 聲明一個只讀常量,一旦聲明就必須立即初始化,否則報錯;聲明之后不能修改,否則也會報錯;
const實際上保證的不是變量的值不可改動,而是變量指向的那個內(nèi)存地址不得改動。使用const聲明引用類型,只能保證指針是固定的,但是指向的數(shù)據(jù)結(jié)構(gòu)內(nèi)的屬性和方法是可變:
let和const聲明的變量只在代碼塊內(nèi)有效(代碼塊:大括號包起來的部分),在代碼塊外調(diào)用會報錯
let和const沒有變量提升,因此在它們聲明之前調(diào)用變量會報錯
let和const不允許在相同作用域內(nèi),重復(fù)聲明一個變量:
function foo1(){ //報錯var a = 1;let a = 1; } function foo2(){ //報錯let a = 1;let a = 2; } function foo3(){//報錯let a= 1;const a = 2; }因此不能在函數(shù)內(nèi)部重新聲明參數(shù):
function foo4(arg){let arg;//報錯 } function foo5(arg){{let arg;//不報錯} }for循環(huán)有個特別之處,循環(huán)語句是一個父作用域,循環(huán)體內(nèi)是一個單獨的子作用域
for (let i = 0; i < 3; i++) {let i = 'abc';console.log(i); } //3*abc只要塊級作用域內(nèi)存在let或const,則它們聲明的變量就綁定了這個區(qū)域,不再受外部的影響,這個區(qū)域稱為暫時性死區(qū)(temporal dead zone),簡稱TDZ
var temp = 123; if(true){temp = 'abc';//reference errorlet temp; } var const = 1; if(true){const=2;//reference errorconst const=3; }TDZ也意味著typeof不再是一個百分百安全的操作
typeof undeclared_variable //undefined typeof x;//reference error let x;有些TDZ比較隱蔽:
function bar(x=y,y=2){return [x,y] } bar();//報錯,參數(shù)x默認(rèn)等于參數(shù)y,而此時y還沒有聲明修改之后
function bar(x=2,y=x){return[x,y]; }; bar();//[2,2]使用let或者const聲明變量時,只有變量還在沒有聲明完成前使用,就會報錯:
var x = x;//undefined let x = x; // reference error const y = y; // reference error總之,TDZ的本質(zhì)就是,只要一進(jìn)入當(dāng)前作用域,所要使用的變量就已經(jīng)存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現(xiàn),才可以獲取和使用該變量
為什么需要塊級作用域?
ES5中只有全局作用域和函數(shù)作用域,沒有塊級作用域,會帶來一些不合常理的場景:
第一種場景,內(nèi)層變量可能會覆蓋外層變量
第二種場景,用來計數(shù)的循環(huán)變量泄露為全局變量:
for(var i=0;i<10;i++){console.log(i); }; console.log(i); //10ES6引入塊級作用域,明確允許在塊級作用域中聲明函數(shù),行為類似于let,在塊級作用域之外不可引用
function f() { console.log('I am outside!'); }(function () {if (false) {// 重復(fù)聲明一次函數(shù)ffunction f() { console.log('I am inside!'); }}f(); }());上面的代碼在ES5中運行,會得到'i an inside!'
// ES5 環(huán)境 function f() { console.log('I am outside!'); }(function () {function f() { console.log('I am inside!'); } //函數(shù)聲明提升if (false) {}f(); }());ES6理論上會得到'I am outside!',但是這樣處理會對老代碼產(chǎn)生很大的影響,為了兼容老代碼,瀏覽器有自己的行為方式:
-允許在塊級作用域內(nèi)聲明函數(shù)
-函數(shù)聲明類似于var,即函數(shù)名提升到全局作用域或塊級作用域頭部,函數(shù)體不提升
-同時,函數(shù)聲明還會提升到所在塊級作用域的頭部
因此,上面的代碼在ES6瀏覽中實際執(zhí)行的是:
要避免在塊級作用域里聲明函數(shù),如果確實需要,則要寫成函數(shù)表達(dá)式,而不是函數(shù)聲明
轉(zhuǎn)載于:https://www.cnblogs.com/azerothmemoir/p/6512453.html
總結(jié)
以上是生活随笔為你收集整理的ES6学习笔记--let和const的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 理解js中this的指向
- 下一篇: nslookup命令详解【转】