摘要:變量聲明結(jié)論存在變量提升,可重復(fù)多次聲明同名變量。和的出現(xiàn),很好地把中定義變量的給埋了,解決了定義同名變量導(dǎo)致變量間相互污染的問題,保證了同一塊級(jí)作用域下,變量名的唯一性。中規(guī)定,函數(shù)本身的作用域在其所在的塊級(jí)作用域當(dāng)中。
引言
萬丈高樓平地起,欲練此功,必先打好基本功: )。
ES6已經(jīng)融入到了我們的日常開發(fā)當(dāng)中,甚至一些ES7的特性也已經(jīng)在普遍使用,但由于瀏覽器的支持問題,ES6的代碼在大多數(shù)情況下,還是需要編譯成ES5才能正常地在各瀏覽器上正常運(yùn)行。
ES6支持6中形式的變量命名方式:var、let、const、function、class、function,本文主要討論的是var、let、const。class和function會(huì)在之后專門討論。
在ES5里面,我們要聲明一個(gè)變量,會(huì)通過三種命令方式來實(shí)現(xiàn),var、隱式聲明、function;
var a = "test"; //var定義一個(gè)變量a,并賦值字符串"test"; b = "test2"; //隱式聲明,在堆變量b賦值字符串"test2"前,未以任何方式聲明變量b,此時(shí)b為全局變量 function f() { cosole.log("haha"); }
隱式聲明聲明變量是一個(gè)很不好的行為,隱式聲明的變量類似于通過var定義一個(gè)變量,且變量的作用域直接指向window對(duì)象,這會(huì)導(dǎo)致變量容易被錯(cuò)誤引用或修改
function f() { var fn = function() { (function() { b = "隱式聲明的變量b"; })(); } fn(); } f(); b; //"隱式聲明的變量b" window.b; //"隱式聲明的變量b"
而在ES6中,變量聲明增加了let和const兩種形式,先看以下例子:
console.log(a); //無報(bào)錯(cuò),輸出undefined var a = "test"; var a = "var again";
通過var聲明的變量存在變量提升一說,同一變量名在相同作用域下能重復(fù)定義,上述代碼執(zhí)行時(shí)會(huì)以以下情形執(zhí)行:先定義一個(gè)變量var a,console.log(a),a = "test";
console.log(son); //報(bào)錯(cuò) Uncaught ReferenceError: son is not defined let son = "James Bond";
let聲明變量不存在變量提升,因此在son被定義前使用son的話,會(huì)報(bào)錯(cuò)
const name; //報(bào)錯(cuò) Uncaught SyntaxError: Missing initializer in const declaration let education; //正常執(zhí)行 console.log(education); //undefined const name1 = "human"; name1 = "cat"; //報(bào)錯(cuò) Uncaught TypeError: Assignment to constant variable.
通過const定義的name、obj是一個(gè)常量,在聲明時(shí)必須對(duì)其進(jìn)行賦值,且賦值后不能進(jìn)行二次賦值,而let聲明的變量在聲明時(shí)可不賦值,后面再賦值,此時(shí)默認(rèn)值為undefined。
const obj = {}; obj; //{} obj.a = "1"; obj; //{a:1}
const 定義的obj在常量中存儲(chǔ)的是obj對(duì)象在棧里指向堆的地址,該指向地址不可改變,而在堆地址里面存放的數(shù)據(jù)不被約束,是可變的。若希望禁止變更obj及其內(nèi)部屬性,Object提供了freeze方法,如下函數(shù)能更好的遞歸凍結(jié)Object對(duì)象
const freezeObj = (obj) => { Object.freeze(obj); Object.keys(obj).forEach((item) => { if(type of(item) === "object") freezeObj(item); }); }
let fruit = "orange"; var fruit = "apple"; //報(bào)錯(cuò) Uncaught SyntaxError: Identifier "fruit" has already been declared
通過let定義的變量在同一作用域下不允許被重復(fù)定義,否則會(huì)報(bào)錯(cuò),const也是如此
var test = "test", test1 = "test1"; { test = "new test"; //Uncaught ReferenceError: test is not defined test1 = "new test1"; //Uncaught ReferenceError: test1 is not defined let test; const test1 = "new test1"; }
通過let、const聲明的變量會(huì)存在 __暫時(shí)性死區(qū)__,即:在聲明該變量的作用域內(nèi),變量已經(jīng)被綁定在該作用域之中,忽略外界存在的同名變量,在該作用域下,該變量在變量聲明之前都不能被使用。
var:
存在變量提升,可重復(fù)多次聲明同名變量。
let:
不存在變量提升,必須先定義再使用,否則報(bào)錯(cuò);
同一作用域下不可重復(fù)定義同名變量,否則報(bào)錯(cuò);
在代碼塊內(nèi),通過let聲明的變量,盡管代碼塊外層有同名變量,代碼塊內(nèi)部在該變量聲明前都不能使用該變量,否則報(bào)錯(cuò)。
const:
不存在變量提升,必須先定義再使用,否則報(bào)錯(cuò);
同一作用域下不可重復(fù)定義同名變量,否則報(bào)錯(cuò);
創(chuàng)建變量的同時(shí)必須對(duì)其賦值,且賦值后不能直接通過=直接替換整個(gè)值否則報(bào)錯(cuò);
在代碼塊內(nèi),通過const聲明的變量,盡管代碼塊外層有同名變量,代碼塊內(nèi)部在該變量聲明前都不能使用該變量,否則報(bào)錯(cuò)。
let 和 const的出現(xiàn),很好地把ES5中var定義變量的Bug給埋了,解決了定義同名變量導(dǎo)致變量間相互污染的問題,保證了同一塊級(jí)作用域下,變量名的唯一性。同時(shí)const定義常量能更直觀地明白常量的意義及其不可修改性。
ES6新增的變量聲明命令存在塊級(jí)作用域
什么是塊級(jí)作用域?{ var a = "test"; let b = "test1"; } console.log(a); //test console.log(b); //Uncaught ReferenceError: b is not defined
這便是塊級(jí)作用域最基本的示例,通過let、const聲明的變量?jī)H能在其代碼塊內(nèi)被使用,該代碼塊內(nèi)部即是一個(gè)塊級(jí)作用域
塊級(jí)作用域有什么用?var a = "test"; function f(){ console.log(a); if(true) { var a = "test1"; } console.log(a); } f(); //undefinded test1
這個(gè)例子輸出的結(jié)果是undefined,原因在于,在f()中,不論if語(yǔ)句判斷是否通過,if內(nèi)部的var a都被變量提升,且變量a均通過var命令聲明,內(nèi)部變量a覆蓋了外部變量a;
換個(gè)寫法再來一遍
let a = "test"; function f(){ console.log(a); if(true) { let a = "test1"; } console.log(a); } f(); //test test
比對(duì)一下兩段代碼的執(zhí)行情況:
看看該代碼的實(shí)際執(zhí)行情況:
var a let a a = "test" a = "test" function f function f f() = {} f() = {} f() f() var a console.log(a); console.log(a) if(true) if(true) let a //此處的a是另一個(gè)a,可以理解為_a,且_a的作用范圍僅在if語(yǔ)句內(nèi) a = "test1" a = "test1"; //類似于_a = "test1" console.log(a) console.log(a) //類似于console.log(_a)
從上面的比對(duì)可以看出,通過let聲明的變量a,不會(huì)被變量提升,且具有塊級(jí)作用域,不會(huì)影響到上層作用域的a變量
再來一個(gè)示例:
for(var i=0;i<10;i++){ console.log("for里面的i:"+i); // 1、2、3......10 } console.log(i); //10
這里定義的循環(huán)計(jì)數(shù)變量i,原本只是想在循環(huán)內(nèi)使用,但由于使用了var聲明,因此不存在塊級(jí)作用域,導(dǎo)致for循環(huán)外也能獲取到了i的值。
ES6中規(guī)定,函數(shù)本身的作用域在其所在的塊級(jí)作用域當(dāng)中。
function fn() { console.log("outside console"); } (function() { if(false) { function fn() { console.log("inside console"); } } fn(); }());
上述代碼中,fn()執(zhí)行結(jié)果會(huì)報(bào)錯(cuò)fn is not a function,因?yàn)樵趂n執(zhí)行的環(huán)境中存在function fn的聲明,聲明被提前,導(dǎo)致fn被提前定義,但沒有被賦值為function。
ES6的函數(shù)自執(zhí)行代碼變得精簡(jiǎn)。
//從 (function() { console.log("test"); })(); //變?yōu)? { console.log("test"); }塊級(jí)作用域結(jié)論
通過使用let const,讓變量存在了塊級(jí)作用域,很好地劃分變量間的作用范圍,避免了以往同名變量相互污染問題;外層變量無法直接讀取內(nèi)層變量,對(duì)內(nèi)層變量具有更好的保密性,內(nèi)外層代碼獨(dú)立執(zhí)行,相互間不影響;精簡(jiǎn)了函數(shù)自執(zhí)行代碼
以上。
文章觀點(diǎn)內(nèi)容如有錯(cuò)誤歡迎指出交流,相互進(jìn)步
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/104167.html
摘要:以下簡(jiǎn)稱是語(yǔ)言的下一代標(biāo)準(zhǔn)。因?yàn)楫?dāng)前版本的是在年發(fā)布的,所以又稱。命令用于規(guī)定模塊的對(duì)外接口,命令用于輸入其他模塊提供的功能。需要特別注意的是,命令規(guī)定的是對(duì)外的接口,必須與模塊內(nèi)部的變量建立一一對(duì)應(yīng)關(guān)系。 ECMAScript 6(以下簡(jiǎn)稱ES6)是JavaScript語(yǔ)言的下一代標(biāo)準(zhǔn)。因?yàn)楫?dāng)前版本的ES6是在2015年發(fā)布的,所以又稱ECMAScript 2015。 最常用的ES6...
摘要:但對(duì)于引用類型的數(shù)據(jù)主要是對(duì)象和數(shù)組,變量指向的內(nèi)存地址,保存的只是一個(gè)引用地址指針,只能保證這個(gè)引用地址指針是固定的,至于它指向的堆內(nèi)存中的存儲(chǔ)的值是不是可變的,就完全不能控制了。 基礎(chǔ)概念 變量是存儲(chǔ)信息的容器,這里需要區(qū)分一下:變量不是指存儲(chǔ)的信息本身,而是指這個(gè)用于存儲(chǔ)信息的容器,可以把變量想象成一個(gè)個(gè)用來裝東西的紙箱子 變量需要聲明,并且建議在聲明的同時(shí)進(jìn)行初始化,如下所...
摘要:以下簡(jiǎn)稱是語(yǔ)言的下一代標(biāo)準(zhǔn)。因?yàn)楫?dāng)前版本的是在年發(fā)布的,所以又稱。用它所聲明的變量,只在命令所在的代碼塊內(nèi)有效。的繼承機(jī)制,實(shí)質(zhì)是先創(chuàng)造父類的實(shí)例對(duì)象所以必須先調(diào)用方法,然后再用子類的構(gòu)造函數(shù)修改。 ECMAScript 6(以下簡(jiǎn)稱ES6)是JavaScript語(yǔ)言的下一代標(biāo)準(zhǔn)。因?yàn)楫?dāng)前版本的ES6是在2015年發(fā)布的,所以又稱ECMAScript 2015。 也就是說,ES6就是E...
摘要:以下簡(jiǎn)稱是語(yǔ)言的下一代標(biāo)準(zhǔn)。的繼承機(jī)制,實(shí)質(zhì)是先創(chuàng)造父類的實(shí)例對(duì)象所以必須先調(diào)用方法,然后再用子類的構(gòu)造函數(shù)修改。總結(jié)以上就是最常用的一些語(yǔ)法,可以說這的語(yǔ)法,在的日常使用中占了追加十分鐘好的嗎分鐘掌握核心內(nèi)容下 ECMAScript 6(以下簡(jiǎn)稱ES6)是JavaScript語(yǔ)言的下一代標(biāo)準(zhǔn)。因?yàn)楫?dāng)前版本的ES6是在2015年發(fā)布的,所以又稱ECMAScript 2015。 也就是說...
摘要:二一個(gè)的解析器在我們正式講解語(yǔ)法之前,我們得先了解下。而則實(shí)際上為新增了塊級(jí)作用域。的繼承機(jī)制,實(shí)質(zhì)是先創(chuàng)造父類的實(shí)例對(duì)象所以必須先調(diào)用方法,然后再用子類的構(gòu)造函數(shù)修改。 隨著google和firfox以及node6.0對(duì)es6的支持,es6語(yǔ)法的定稿使它越來越受到關(guān)注,尤其是react項(xiàng)目基本上都是用es6來寫的。是時(shí)候從es5到es6轉(zhuǎn)變了showImg(http://static...
閱讀 2159·2023-04-26 00:16
閱讀 3573·2021-11-15 11:38
閱讀 3300·2019-08-30 12:50
閱讀 3259·2019-08-29 13:59
閱讀 839·2019-08-29 13:54
閱讀 2621·2019-08-29 13:42
閱讀 3411·2019-08-26 11:45
閱讀 2268·2019-08-26 11:36