摘要:不允許在相同作用域內(nèi),重復(fù)聲明同一個(gè)變量。如但是在中則不再必要了,我們可以通過(guò)塊級(jí)作用域就能夠?qū)崿F(xiàn)本次主要針對(duì)中的變量和塊級(jí)作用域進(jìn)行了梳理學(xué)習(xí),并且通過(guò)與的實(shí)現(xiàn)方式進(jìn)行了對(duì)比,從而看出其變化以及快捷與便利。
ECMAScript 6.0(以下簡(jiǎn)稱 ES6)是 JavaScript 語(yǔ)言的下一代標(biāo)準(zhǔn),已經(jīng)在 2015 年 6 月正式發(fā)布了。它的目標(biāo),是使得 JavaScript 語(yǔ)言可以用來(lái)編寫(xiě)復(fù)雜的大型應(yīng)用程序,成為企業(yè)級(jí)開(kāi)發(fā)語(yǔ)言。
ES6的出現(xiàn)已經(jīng)很久了,由于之前的項(xiàng)目只是基于ES5以及之前的版本內(nèi)容進(jìn)行開(kāi)發(fā)的,所以沒(méi)有系統(tǒng)性的梳理學(xué)習(xí)ES6的相關(guān)知識(shí)。感覺(jué)自己已經(jīng)被發(fā)展的車(chē)輪落下了好遠(yuǎn)好遠(yuǎn)(@﹏@)~,所以在接下來(lái)這段時(shí)間針對(duì)性的進(jìn)行學(xué)習(xí)整理,希望能夠讓自己有所提高,也希望能幫助和我一樣的人……
變量 常量 const命令 常量的定義在之前的版本ES5甚至更早的版本(后面統(tǒng)稱ES5)中,很少能夠聽(tīng)到常量的概念,我們也知道,JS不同于其他的語(yǔ)言,如Java、C++等,有常量的概念。雖然通過(guò)其他的方法能夠達(dá)到實(shí)現(xiàn)常量的方法,但是并不直接、方便。
如可通過(guò)下述方式進(jìn)行常量的實(shí)現(xiàn):
// 此處在window對(duì)象上面定義了一個(gè)圓周率變量PI,使之不能被修改,模擬常量 Object.defineProperty(window, "PI", { value: 3.1415926, writable: false })
在ES6中,定義一個(gè)常量則非常簡(jiǎn)單,通過(guò)const進(jìn)行聲明即可。
const聲明一個(gè)只讀的常量。一旦聲明,常量的值就不能改變。
const PI = 3.1415926;
const聲明的變量不得改變值,這意味著,const一旦聲明變量,就必須立即初始化,不能留到以后賦值。
const定義常量的本質(zhì)const實(shí)際上保證的,并不是變量的值不得改動(dòng),而是變量指向的那個(gè)內(nèi)存地址不得改動(dòng)。對(duì)于簡(jiǎn)單類(lèi)型的數(shù)據(jù)(數(shù)值、字符串、布爾值),值就保存在變量指向的那個(gè)內(nèi)存地址,因此等同于常量。但對(duì)于復(fù)合類(lèi)型的數(shù)據(jù)(主要是對(duì)象和數(shù)組),變量指向的內(nèi)存地址,保存的只是一個(gè)指針,const只能保證這個(gè)指針是固定的,至于它指向的數(shù)據(jù)結(jié)構(gòu)是不是可變的,就完全不能控制了。
如:
const foo = {}; // 為 foo 添加一個(gè)屬性,可以成功 foo.prop = 123; foo.prop // 123 // 將 foo 指向另一個(gè)對(duì)象,就會(huì)報(bào)錯(cuò) foo = {}; // TypeError: "foo" is read-onlylet命令
在ES6中新增了let命令,可以用來(lái)聲明一個(gè)變量,作用類(lèi)似于之前常用的var,但是和var聲明的變量其有效的作用域不同,let聲明的變量只在let命令所在的代碼塊內(nèi)有效。
如:
{ let a = 1; var b = 2; } console.log(a); // Uncaught ReferenceError: a is not defined console.log(b); // 2
通過(guò)上面代碼的執(zhí)行結(jié)果來(lái)看能夠看出,let聲明的變量只在它所在的代碼塊中有效,即{}所在的代碼塊內(nèi)。
那么let聲明的變量在什么情況下會(huì)比較有用呢?先讓我們來(lái)看下下面一段代碼:
var arrays = []; for (var i = 0; i <= 2; i++) { arrays[i] = function() { return i * 2; } } console.table([ arrays[0](), arrays[1](), arrays[2]() ])
可能我們預(yù)期的結(jié)果是顯示0,2,4,但是從執(zhí)行代碼的結(jié)果中能夠看出,得到的卻是6,6,6,這是為什么呢?
首先我們上面是使用的var聲明的一個(gè)i變量,此處會(huì)有一個(gè)變量提升,相當(dāng)于在for循環(huán)外面聲明了var i = 0變量。當(dāng)在for循環(huán)中時(shí),arrays[i]中的i即為每次循環(huán)的i的值(0,1,2),但是在函數(shù)體中并沒(méi)有將i變量取值為每次循環(huán)的值,它只是對(duì)變量的一個(gè)引用,并不是值的引用。當(dāng)在執(zhí)行循環(huán)中的函數(shù)體時(shí),i變量已經(jīng)變成了3,所以每次的結(jié)構(gòu)輸出都是6。這個(gè)時(shí)候,ES6中的let命令就能夠滿足我們的要求了。
var arrays = []; for (let i = 0; i <= 2; i++) { arrays[i] = function() { return i * 2; } } console.table([ arrays[0](), arrays[1](), arrays[2]() ])
上面代碼中變量i只在for循環(huán)體內(nèi)有效,只在其所在的塊作用域內(nèi)有效,每次for循環(huán)時(shí)會(huì)將i變量的值保存在其對(duì)應(yīng)的塊作用域中(for循環(huán)的{}),每一輪循環(huán)都是重新生成一個(gè)新的作用域,在執(zhí)行for循環(huán)中聲明的函數(shù)時(shí),都會(huì)獲取其對(duì)應(yīng)作用域內(nèi)的i的值。這部分涉及到的作用域相關(guān)的概念,我們后面會(huì)說(shuō)到。
1、在前面提到過(guò),var命令聲明的變量會(huì)發(fā)生變量提升的現(xiàn)象,即變量可以在聲明之前使用,值為undefined。按照一般的邏輯來(lái)說(shuō),變量應(yīng)該在聲明語(yǔ)句之后才可以使用。所以在ES6中為了糾正這個(gè)現(xiàn)象,let命令改變了語(yǔ)法行為,它所聲明的變量一定要在聲明后使用,否則報(bào)錯(cuò)。
2、只要在塊級(jí)作用域中存在let命令,它所聲明的變量就“綁定”(binding)這個(gè)區(qū)域,不再受外部的影響。
var tmp = 123; if (true) { tmp = "abc"; // ReferenceError let tmp; }
ES6 明確規(guī)定,如果區(qū)塊中存在let和const命令,這個(gè)區(qū)塊對(duì)這些命令聲明的變量,從一開(kāi)始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會(huì)報(bào)錯(cuò)。
總之,在代碼塊內(nèi),使用let命令聲明變量之前,該變量都是不可用的。這在語(yǔ)法上,稱為“暫時(shí)性死區(qū)”(temporal dead zone,簡(jiǎn)稱 TDZ)。
3、typeof不再是一個(gè)完全安全的操作。之前我們知道,針對(duì)一個(gè)沒(méi)有生命的變量調(diào)用typeof方法時(shí)會(huì)返回undefined,但是在上面出現(xiàn)的“暫時(shí)性死區(qū)”中,typeof將會(huì)被報(bào)錯(cuò)。
使用let聲明變量時(shí),只要變量在還沒(méi)有聲明完成前使用,就會(huì)報(bào)錯(cuò)。
4、let不允許在相同作用域內(nèi),重復(fù)聲明同一個(gè)變量。
塊級(jí)作用域 為什么需要塊級(jí)作用域1、內(nèi)層變量可能會(huì)覆蓋外層變量
var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = "hello world"; } } f(); // undefined
內(nèi)層的tmp變量由于變量提升覆蓋了外層的tmp變量,導(dǎo)致輸出不符合預(yù)期
2、計(jì)數(shù)的循環(huán)變量泄露為全局變量
我們上面用到的for循環(huán)的例子就是這個(gè)現(xiàn)象的證明,var聲明的變量i在循環(huán)結(jié)束后泄露成了全局變量。
ES6的塊級(jí)作用域在ES6中{}包裹的塊即為一個(gè)塊級(jí)作用域,并且塊級(jí)作用域支持嵌套,如
{{{{{let insane = "Hello World"}}}}}; // 5層塊級(jí)作用域
并且外層作用域不能讀取內(nèi)層作用域的變量;
內(nèi)層作用域可以定義外層作用域的同名變量。
在之前的版本中,當(dāng)我們想要實(shí)現(xiàn)一個(gè)變量只在一個(gè)代碼塊中運(yùn)行,我們往往需要通過(guò)使用立即執(zhí)行函數(shù)來(lái)實(shí)現(xiàn)。如
(function () { var tmp = ...; ... }());
但是在ES6中則不再必要了,我們可以通過(guò)塊級(jí)作用域就能夠?qū)崿F(xiàn)
{ let tmp = ...; ... }
本次主要針對(duì)ES6中的變量和塊級(jí)作用域進(jìn)行了梳理學(xué)習(xí),并且通過(guò)與ES5的實(shí)現(xiàn)方式進(jìn)行了對(duì)比,從而看出其變化以及快捷與便利。希望能夠?qū)δ兴鶐椭?,如有?xiě)的不對(duì)的地方望請(qǐng)指正,從而共同進(jìn)步。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/107672.html
摘要:不同的是函數(shù)體并不會(huì)再被提升至函數(shù)作用域頭部,而僅會(huì)被提升到塊級(jí)作用域頭部避免全局變量在計(jì)算機(jī)編程中,全局變量指的是在所有作用域中都能訪問(wèn)的變量。 ES6 變量作用域與提升:變量的生命周期詳解從屬于筆者的現(xiàn)代 JavaScript 開(kāi)發(fā):語(yǔ)法基礎(chǔ)與實(shí)踐技巧系列文章。本文詳細(xì)討論了 JavaScript 中作用域、執(zhí)行上下文、不同作用域下變量提升與函數(shù)提升的表現(xiàn)、頂層對(duì)象以及如何避免創(chuàng)建...
摘要:聲明之函數(shù)作用域和全局作用域。塊級(jí)作用域不能重復(fù)聲明臨時(shí)性死區(qū)等特性用來(lái)解決變量存在的種種問(wèn)題。塊級(jí)作用域終于在外面訪問(wèn)不到了。一些常量聲明使用聲明的變量名全部大寫(xiě)。 ES5之前javascript語(yǔ)言只有函數(shù)作用域和全局作用域,使用var來(lái)聲明變量,var聲明的變量還存在變量提升使人困惑不已。我們先來(lái)復(fù)習(xí)一下ES5的var聲明,再對(duì)比學(xué)習(xí)let和const 。 var var聲明之函...
摘要:返回一個(gè)對(duì)象,遍歷對(duì)象自身和繼承的所有可枚舉屬性不含,與相同和在紅寶書(shū)中就已經(jīng)提到過(guò)屬性,表示的是引用類(lèi)型實(shí)例的一個(gè)內(nèi)部指針,指向該實(shí)例的構(gòu)造函數(shù)的原型對(duì)象。 半個(gè)月前就決定要將ES6的學(xué)習(xí)總結(jié)一遍,結(jié)果拖延癥一犯,半個(gè)月就過(guò)去了,現(xiàn)在補(bǔ)起來(lái),慚愧慚愧。 阮一峰的《ES6標(biāo)準(zhǔn)入門(mén)》這本書(shū)有300頁(yè)左右,除了幾個(gè)新的API和js語(yǔ)法的擴(kuò)展,真正有價(jià)值的內(nèi)容并不多。所謂存在即合理,每部分的...
摘要:塊級(jí)作用域存在于函數(shù)內(nèi)部塊中字符和之間的區(qū)域和塊級(jí)聲明用于聲明在指定塊的作用域之外無(wú)法訪問(wèn)的變量。和都是塊級(jí)聲明的一種。值得一提的是聲明不允許修改綁定,但允許修改值。這意味著當(dāng)用聲明對(duì)象時(shí)沒(méi)有問(wèn)題報(bào)錯(cuò)臨時(shí)死區(qū)臨時(shí)死區(qū),簡(jiǎn)寫(xiě)為。 塊級(jí)作用域的出現(xiàn) 通過(guò) var 聲明的變量存在變量提升的特性: if (condition) { var value = 1; } console.lo...
摘要:但對(duì)于引用類(lèi)型的數(shù)據(jù)主要是對(duì)象和數(shù)組,變量指向的內(nèi)存地址,保存的只是一個(gè)引用地址指針,只能保證這個(gè)引用地址指針是固定的,至于它指向的堆內(nèi)存中的存儲(chǔ)的值是不是可變的,就完全不能控制了。 基礎(chǔ)概念 變量是存儲(chǔ)信息的容器,這里需要區(qū)分一下:變量不是指存儲(chǔ)的信息本身,而是指這個(gè)用于存儲(chǔ)信息的容器,可以把變量想象成一個(gè)個(gè)用來(lái)裝東西的紙箱子 變量需要聲明,并且建議在聲明的同時(shí)進(jìn)行初始化,如下所...
閱讀 3026·2021-11-17 09:33
閱讀 1758·2021-10-12 10:13
閱讀 2613·2021-09-22 15:48
閱讀 2488·2019-08-29 17:19
閱讀 2646·2019-08-26 11:50
閱讀 1626·2019-08-26 10:37
閱讀 1790·2019-08-23 16:54
閱讀 2973·2019-08-23 14:14