飯飯的ES6完全筆記(1)——let和const

飯飯的ES6完全筆記(1)——let和const

歡迎到我的博客下與我討論飯飯的ES6完全筆記(1)——let和const

之前對于JS的一些新規(guī)范總是只會用一些很常用的比如箭頭函數(shù)等,最近剛好重新系統(tǒng)學(xué)習(xí)一下ES6的拓展語法给猾,對學(xué)習(xí)過程做一些記錄

ES6介紹

ES6簡介

ECMAScript 6.0(以下簡稱ES6)是JavaScript語言的下一代標(biāo)準(zhǔn)娇唯,已經(jīng)在2015年6月正式發(fā)布了挤忙。它的目標(biāo),是使得JavaScript語言可以用來編寫復(fù)雜的大型應(yīng)用程序藤为,成為企業(yè)級開發(fā)語言今阳。

ECMAScript和JavaScript的關(guān)系

一個常見的問題是,ECMAScript和JavaScript到底是什么關(guān)系朴读?

要講清楚這個問題,需要回顧歷史走趋。1996年11月衅金,JavaScript的創(chuàng)造者Netscape公司,決定將JavaScript提交給國際標(biāo)準(zhǔn)化組織ECMA,希望這種語言能夠成為國際標(biāo)準(zhǔn)氮唯。次年鉴吹,ECMA發(fā)布262號標(biāo)準(zhǔn)文件(ECMA-262)的第一版,規(guī)定了瀏覽器腳本語言的標(biāo)準(zhǔn)惩琉,并將這種語言稱為ECMAScript豆励,這個版本就是1.0版。

該標(biāo)準(zhǔn)從一開始就是針對JavaScript語言制定的瞒渠,但是之所以不叫JavaScript良蒸,有兩個原因。一是商標(biāo)伍玖,Java是Sun公司的商標(biāo)嫩痰,根據(jù)授權(quán)協(xié)議,只有Netscape公司可以合法地使用JavaScript這個名字窍箍,且JavaScript本身也已經(jīng)被Netscape公司注冊為商標(biāo)串纺。二是想體現(xiàn)這門語言的制定者是ECMA,不是Netscape椰棘,這樣有利于保證這門語言的開放性和中立性造垛。

因此,ECMAScript和JavaScript的關(guān)系是晰搀,前者是后者的規(guī)格,后者是前者的一種實(shí)現(xiàn)(另外的ECMAScript方言還有Jscript和ActionScript)办斑。日常場合外恕,這兩個詞是可以互換的。

ES6與ECMAScript 2015的關(guān)系

媒體里面經(jīng)诚绯幔可以看到”ECMAScript 2015“這個詞鳞疲,它與ES6是什么關(guān)系呢?

2011年蠕蚜,ECMAScript 5.1版發(fā)布后尚洽,就開始制定6.0版了。因此靶累,”ES6”這個詞的原意腺毫,就是指JavaScript語言的下一個版本。

但是挣柬,因?yàn)檫@個版本引入的語法功能太多潮酒,而且制定過程當(dāng)中,還有很多組織和個人不斷提交新功能邪蛔。事情很快就變得清楚了急黎,不可能在一個版本里面包括所有將要引入的功能。常規(guī)的做法是先發(fā)布6.0版,過一段時間再發(fā)6.1版勃教,然后是6.2版淤击、6.3版等等。

但是故源,標(biāo)準(zhǔn)的制定者不想這樣做污抬。他們想讓標(biāo)準(zhǔn)的升級成為常規(guī)流程:任何人在任何時候,都可以向標(biāo)準(zhǔn)委員會提交新語法的提案心软,然后標(biāo)準(zhǔn)委員會每個月開一次會壕吹,評估這些提案是否可以接受,需要哪些改進(jìn)删铃。如果經(jīng)過多次會議以后耳贬,一個提案足夠成熟了,就可以正式進(jìn)入標(biāo)準(zhǔn)了猎唁。這就是說咒劲,標(biāo)準(zhǔn)的版本升級成為了一個不斷滾動的流程,每個月都會有變動诫隅。

標(biāo)準(zhǔn)委員會最終決定腐魂,標(biāo)準(zhǔn)在每年的6月份正式發(fā)布一次,作為當(dāng)年的正式版本逐纬。接下來的時間蛔屹,就在這個版本的基礎(chǔ)上做改動,直到下一年的6月份豁生,草案就自然變成了新一年的版本兔毒。這樣一來,就不需要以前的版本號了甸箱,只要用年份標(biāo)記就可以了育叁。

ES6的第一個版本,就這樣在2015年6月發(fā)布了芍殖,正式名稱就是《ECMAScript 2015標(biāo)準(zhǔn)》(簡稱ES2015)豪嗽。2016年6月,小幅修訂的《ECMAScript 2016標(biāo)準(zhǔn)》(簡稱ES2016)如期發(fā)布豌骏,這個版本可以看作是ES6.1版龟梦,因?yàn)閮烧叩牟町惙浅P。ㄖ恍略隽藬?shù)組實(shí)例的includes方法和指數(shù)運(yùn)算符)肯适,基本上是同一個標(biāo)準(zhǔn)变秦。根據(jù)計劃,2017年6月將發(fā)布ES2017標(biāo)準(zhǔn)框舔。

因此蹦玫,ES6既是一個歷史名詞赎婚,也是一個泛指,含義是5.1版以后的JavaScript的下一代標(biāo)準(zhǔn)樱溉,涵蓋了ES2015挣输、ES2016、ES2017等等福贞,而ES2015則是正式名稱撩嚼,特指該年發(fā)布的正式版本的語言標(biāo)準(zhǔn)。本書中提到“ES6”的地方挖帘,一般是指ES2015標(biāo)準(zhǔn)完丽,但有時也是泛指“下一代JavaScript語言”。

ECMAScript的歷史

ES6從開始制定到最后發(fā)布拇舀,整整用了15年逻族。

前面提到,ECMAScript 1.0是1997年發(fā)布的骄崩,接下來的兩年聘鳞,連續(xù)發(fā)布了ECMAScript 2.0(1998年6月)和ECMAScript 3.0(1999年12月)。3.0版是一個巨大的成功要拂,在業(yè)界得到廣泛支持抠璃,成為通行標(biāo)準(zhǔn),奠定了JavaScript語言的基本語法脱惰,以后的版本完全繼承搏嗡。直到今天,初學(xué)者一開始學(xué)習(xí)JavaScript拉一,其實(shí)就是在學(xué)3.0版的語法彻况。

2000年,ECMAScript 4.0開始醞釀舅踪。這個版本最后沒有通過,但是它的大部分內(nèi)容被ES6繼承了良蛮。因此抽碌,ES6制定的起點(diǎn)其實(shí)是2000年。

為什么ES4沒有通過呢决瞳?因?yàn)檫@個版本太激進(jìn)了货徙,對ES3做了徹底升級,導(dǎo)致標(biāo)準(zhǔn)委員會的一些成員不愿意接受皮胡。ECMA的第39號技術(shù)專家委員會(Technical Committee 39痴颊,簡稱TC39)負(fù)責(zé)制訂ECMAScript標(biāo)準(zhǔn),成員包括Microsoft屡贺、Mozilla蠢棱、Google等大公司锌杀。

2007年10月,ECMAScript 4.0版草案發(fā)布泻仙,本來預(yù)計次年8月發(fā)布正式版本糕再。但是,各方對于是否通過這個標(biāo)準(zhǔn)玉转,發(fā)生了嚴(yán)重分歧突想。以Yahoo、Microsoft究抓、Google為首的大公司猾担,反對JavaScript的大幅升級,主張小幅改動刺下;以JavaScript創(chuàng)造者Brendan Eich為首的Mozilla公司绑嘹,則堅(jiān)持當(dāng)前的草案。

2008年7月怠李,由于對于下一個版本應(yīng)該包括哪些功能圾叼,各方分歧太大,爭論過于激烈捺癞,ECMA開會決定夷蚊,中止ECMAScript 4.0的開發(fā),將其中涉及現(xiàn)有功能改善的一小部分髓介,發(fā)布為ECMAScript 3.1惕鼓,而將其他激進(jìn)的設(shè)想擴(kuò)大范圍,放入以后的版本唐础,由于會議的氣氛箱歧,該版本的項(xiàng)目代號起名為Harmony(和諧)。會后不久一膨,ECMAScript 3.1就改名為ECMAScript 5呀邢。

2009年12月,ECMAScript 5.0版正式發(fā)布豹绪。Harmony項(xiàng)目則一分為二价淌,一些較為可行的設(shè)想定名為JavaScript.next繼續(xù)開發(fā),后來演變成ECMAScript 6瞒津;一些不是很成熟的設(shè)想蝉衣,則被視為JavaScript.next.next,在更遠(yuǎn)的將來再考慮推出巷蚪。TC39委員會的總體考慮是病毡,ES5與ES3基本保持兼容,較大的語法修正和新功能加入屁柏,將由JavaScript.next完成啦膜。當(dāng)時有送,JavaScript.next指的是ES6,第六版發(fā)布以后功戚,就指ES7娶眷。TC39的判斷是,ES5會在2013年的年中成為JavaScript開發(fā)的主流標(biāo)準(zhǔn)啸臀,并在此后五年中一直保持這個位置届宠。

2011年6月,ECMAscript 5.1版發(fā)布乘粒,并且成為ISO國際標(biāo)準(zhǔn)(ISO/IEC 16262:2011)豌注。

2013年3月,ECMAScript 6草案凍結(jié)灯萍,不再添加新功能轧铁。新的功能設(shè)想將被放到ECMAScript 7。

2013年12月旦棉,ECMAScript 6草案發(fā)布齿风。然后是12個月的討論期,聽取各方反饋绑洛。

2015年6月救斑,ECMAScript 6正式通過,成為國際標(biāo)準(zhǔn)真屯。從2000年算起脸候,這時已經(jīng)過去了15年。

兼容性

目前大部分瀏覽器已經(jīng)兼容ES6绑蔫,甚至在開發(fā)中像React這樣的框架已經(jīng)開始使用ES7的語法進(jìn)行開發(fā)运沦,截止2020年8月,市面上大部分瀏覽器的兼容性如下

腳本引擎 應(yīng)用程序 ES5 ES6 ES7 ES2016+
Chakra Microsoft Edge 18 100% 96% 100% 48%
SpiderMonkey Firefox 67 100% 98% 100% 83%
Chrome V8 Google Chrome 75配深、Opera 62 100% 98% 100% 98%
JavaScriptCore(Nitro) Safari 12.1 99% 99% 100% 87%

Babel轉(zhuǎn)碼器

Babel是一個廣泛使用的ES6轉(zhuǎn)碼器携添,可以將ES6代碼轉(zhuǎn)為ES5代碼,從而在現(xiàn)有環(huán)境執(zhí)行篓叶。這意味著薪寓,你可以用ES6的方式編寫程序,又不用擔(dān)心現(xiàn)有環(huán)境是否支持澜共。

let和const

let

let類似于var,用于聲明變量锥腻,但不同于var嗦董,let聲明的變量只在自身所在代碼塊內(nèi)有效

{
  let a = 10;
  var b = 1;
}

a // ReferenceError: a is not defined.
b // 1

常用于循環(huán)遍歷中,再也不用擔(dān)心循環(huán)變量沖突了

var a = [1 ,2 ,3]
for(let i = 0; i < 3; i++){
  console.log(a[i] ++)
}
// 1
// 2
// 3

for(let i = 0; i < 3; i++){
  console.log(a[i])
}
// 2
// 3
// 4

以下是一些注意事項(xiàng)

不存在變量提升

對于var 來說瘦黑,只要在腳本中聲明了變量京革,該變量就已經(jīng)存在奇唤。但對于let來說,只有在變量聲明之后才可以使用

// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;

// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;

暫時性死區(qū)

ES6 明確規(guī)定匹摇,如果區(qū)塊中存在letconst命令咬扇,這個區(qū)塊對這些命令聲明的變量,從一開始就形成了封閉作用域廊勃。凡是在聲明之前就使用這些變量懈贺,就會報錯。

總之坡垫,在代碼塊內(nèi)梭灿,使用let命令聲明變量之前,該變量都是不可用的冰悠。這在語法上堡妒,稱為“暫時性死區(qū)”(temporal dead zone,簡稱 TDZ)溉卓。

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

不能重復(fù)聲明

// 報錯
function func() {
  let a = 10;
  var a = 1;
}

const

const 用于聲明一個只讀常量皮迟,聲明后便不得改變,這意味著聲明后需要立刻初始化桑寨。

const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.

const foo;
// SyntaxError: Missing initializer in const declaration

此外伏尼,const和let一樣,只在聲明的塊級作用域內(nèi)有效

if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined

同樣的西疤,const也存在不能變量提升烦粒,暫時性死區(qū),不能重復(fù)聲明等情況

常量對象陷阱

const實(shí)際保證的是該變量指向的地址內(nèi)容不能改動代赁,但對于復(fù)合型數(shù)據(jù)扰她,實(shí)際只是一個指向?qū)嶋H數(shù)據(jù)的指針。const只能保證這個指針是固定的芭碍,但不能保證指針指向數(shù)據(jù)是固定的徒役。因此將一個對象聲明為const要非常小心。

// 對象
const foo = {};

// 為 foo 添加一個屬性窖壕,可以成功
foo.prop = 123;
foo.prop // 123

// 將 foo 指向另一個對象忧勿,就會報錯
foo = {}; // TypeError: "foo" is read-only

// 數(shù)組
const a = [];
a.push('Hello'); // 可執(zhí)行
a.length = 0;    // 可執(zhí)行
a = ['Dave'];    // 報錯

如果真的想凍結(jié)一個對象≌胺恚可以使用Object.freeze方法

const foo = Object.freeze({});

// 常規(guī)模式時鸳吸,下面一行不起作用;
// 嚴(yán)格模式時速勇,該行會報錯
foo.prop = 123;

塊級作用域

const和let實(shí)際上為 JavaScript 新增了塊級作用域晌砾, ES6允許作用域嵌套,內(nèi)層作用域可以重新定義外層作用域的變量

{{{{
  {let insane = 'Hello World'}
  console.log(insane); // 報錯
}}}};

{{{{
  let insane = 'Hello World';
  {let insane = 'Hello World'}
}}}};

對于塊級作用域內(nèi)的函數(shù)烦磁,由于ES6中一些神奇的規(guī)定养匈,使得目前這個規(guī)則變得非常奇怪哼勇,所以應(yīng)該避免在塊級作用域內(nèi)聲明函數(shù),如果確實(shí)需要也應(yīng)該寫成表達(dá)式

// 塊級作用域內(nèi)部的函數(shù)聲明語句呕乎,建議不要使用
{
  let a = 'secret';
  function f() {
    return a;
  }
}

// 塊級作用域內(nèi)部积担,優(yōu)先使用函數(shù)表達(dá)式
{
  let a = 'secret';
  let f = function () {
    return a;
  };
}

還有一個需要注意的地方,es6的塊級作用域必須要大括號猬仁,沒有大括號JS會認(rèn)為不存在塊級作用域帝璧,所以有l(wèi)et和const等塊級作用域的塊即使只有一行也不能省略大括號

// 第一種寫法,報錯
if (true) let x = 1;

// 第二種寫法逐虚,不報錯
if (true) {
  let x = 1;
}

頂層對象

頂層對象聋溜,是指在環(huán)境中的全局變量,在瀏覽器中一般指Windows叭爱,在Node中指global對象撮躁。需要注意的是,ES6為了改善JS編程中全局變量到處跑的狀況买雾,規(guī)定let和const所聲明的變量不屬于頂層對象的屬性把曼,另一方面,為了兼容原來的規(guī)定漓穿,var和function所聲明的變量仍然是頂層變量的屬性嗤军。因此,在之后的編程中我們應(yīng)該養(yǎng)成良好的習(xí)慣用let和const去替換var和直接聲明函數(shù)晃危,避免不必要的麻煩叙赚。

var a = 1;
// 如果在 Node 的 REPL 環(huán)境,可以寫成 global.a
// 或者采用通用方法僚饭,寫成 this.a
window.a // 1

let b = 1;
window.b // undefined

調(diào)用頂層對象

目前JS的頂層對象十分混亂

  • 瀏覽器里面震叮,頂層對象是window,但 Node 和 Web Worker 沒有window鳍鸵。
  • 瀏覽器和 Web Worker 里面苇瓣,self也指向頂層對象,但是 Node 沒有self偿乖。
  • Node 里面击罪,頂層對象是global,但其他環(huán)境都不支持贪薪。

同一段代碼為了能夠在各種環(huán)境媳禁,都能取到頂層對象,現(xiàn)在一般是使用this變量画切,但是有局限性竣稽。

  • 前模塊,ES6 模塊中this返回的是undefined
  • 函數(shù)里面的this丧枪,如果函數(shù)不是作為對象的方法運(yùn)行,而是單純作為函數(shù)運(yùn)行庞萍,this會指向頂層對象拧烦。但是,嚴(yán)格模式下钝计,這時this會返回undefined恋博。
  • 不管是嚴(yán)格模式,還是普通模式私恬,new Function('return this')()债沮,總是會返回全局對象。但是本鸣,如果瀏覽器用了 CSP(Content Security Policy疫衩,內(nèi)容安全策略),那么eval荣德、new Function這些方法都可能無法使用闷煤。

ES2020中,引入了globalThis作為統(tǒng)一的頂層對象來進(jìn)行調(diào)用涮瞻。也就是說鲤拿,任何環(huán)境下,globalThis都是存在的署咽,都可以從它拿到頂層對象近顷,指向全局環(huán)境下的this

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宁否,一起剝皮案震驚了整個濱河市窒升,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌家淤,老刑警劉巖异剥,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異絮重,居然都是意外死亡冤寿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門青伤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來督怜,“玉大人,你說我怎么就攤上這事狠角『鸥埽” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長姨蟋。 經(jīng)常有香客問我屉凯,道長,這世上最難降的妖魔是什么眼溶? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任悠砚,我火速辦了婚禮,結(jié)果婚禮上堂飞,老公的妹妹穿的比我還像新娘灌旧。我一直安慰自己,他們只是感情好绰筛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布枢泰。 她就那樣靜靜地躺著,像睡著了一般铝噩。 火紅的嫁衣襯著肌膚如雪衡蚂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天薄榛,我揣著相機(jī)與錄音讳窟,去河邊找鬼。 笑死敞恋,一個胖子當(dāng)著我的面吹牛丽啡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播硬猫,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼补箍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了啸蜜?” 一聲冷哼從身側(cè)響起坑雅,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎衬横,沒想到半個月后裹粤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜂林,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年遥诉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片噪叙。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡矮锈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出睁蕾,到底是詐尸還是另有隱情苞笨,我是刑警寧澤债朵,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站瀑凝,受9級特大地震影響序芦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粤咪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一芝加、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧射窒,春花似錦、人聲如沸将塑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽点寥。三九已至艾疟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間敢辩,已是汗流浹背蔽莱。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留戚长,地道東北人盗冷。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像同廉,于是被迫代替她去往敵國和親仪糖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355