成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

通俗易懂理解ES6 - 變量聲明命令及其塊級作用域

Olivia / 3172人閱讀

摘要:變量聲明結(jié)論存在變量提升,可重復(fù)多次聲明同名變量。和的出現(xiàn),很好地把中定義變量的給埋了,解決了定義同名變量導(dǎo)致變量間相互污染的問題,保證了同一塊級作用域下,變量名的唯一性。中規(guī)定,函數(shù)本身的作用域在其所在的塊級作用域當(dāng)中。

引言

萬丈高樓平地起,欲練此功,必先打好基本功: )。

ES6已經(jīng)融入到了我們的日常開發(fā)當(dāng)中,甚至一些ES7的特性也已經(jīng)在普遍使用,但由于瀏覽器的支持問題,ES6的代碼在大多數(shù)情況下,還是需要編譯成ES5才能正常地在各瀏覽器上正常運行。
ES6支持6中形式的變量命名方式:var、let、constfunction、classfunction,本文主要討論的是varlet、const。classfunction會在之后專門討論。

變量聲明

在ES5里面,我們要聲明一個變量,會通過三種命令方式來實現(xiàn),var隱式聲明、function

var a = "test";     //var定義一個變量a,并賦值字符串"test";
b = "test2";        //隱式聲明,在堆變量b賦值字符串"test2"前,未以任何方式聲明變量b,此時b為全局變量
function f() {
    cosole.log("haha");
}


隱式聲明聲明變量是一個很不好的行為,隱式聲明的變量類似于通過var定義一個變量,且變量的作用域直接指向window對象,這會導(dǎo)致變量容易被錯誤引用或修改

function f() {
    var fn = function() {
        (function() {
            b = "隱式聲明的變量b";
        })();
    }
    fn();
}
f();
b;          //"隱式聲明的變量b"
window.b;   //"隱式聲明的變量b"


ES6-變量聲明的let和const

而在ES6中,變量聲明增加了letconst兩種形式,先看以下例子:

console.log(a);     //無報錯,輸出undefined
var a = "test";
var a = "var again";

通過var聲明的變量存在變量提升一說,同一變量名在相同作用域下能重復(fù)定義,上述代碼執(zhí)行時會以以下情形執(zhí)行:先定義一個變量var a,console.log(a),a = "test";

console.log(son);     //報錯 Uncaught ReferenceError: son is not defined
let son = "James Bond";

let聲明變量不存在變量提升,因此在son被定義前使用son的話,會報錯

const name;            //報錯 Uncaught SyntaxError: Missing initializer in const declaration
let education;              //正常執(zhí)行
console.log(education);     //undefined

const name1 = "human";
name1 = "cat";         //報錯 Uncaught TypeError: Assignment to constant variable.

通過const定義的name、obj是一個常量,在聲明時必須對其進行賦值,且賦值后不能進行二次賦值,而let聲明的變量在聲明時可不賦值,后面再賦值,此時默認值為undefined

const obj = {};
obj;                //{}
obj.a = "1";
obj;                //{a:1}

const 定義的obj在常量中存儲的是obj對象在里指向的地址,該指向地址不可改變,而在地址里面存放的數(shù)據(jù)不被約束,是可變的。若希望禁止變更obj及其內(nèi)部屬性,Object提供了freeze方法,如下函數(shù)能更好的遞歸凍結(jié)Object對象

const freezeObj = (obj) => {
    Object.freeze(obj);
    Object.keys(obj).forEach((item) => {
        if(type of(item) === "object") freezeObj(item);
    });
}


let fruit = "orange";
var fruit = "apple";    //報錯 Uncaught SyntaxError: Identifier "fruit" has already been declared

通過let定義的變量在同一作用域下不允許被重復(fù)定義,否則會報錯,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聲明的變量會存在 __暫時性死區(qū)__,即:在聲明該變量的作用域內(nèi),變量已經(jīng)被綁定在該作用域之中,忽略外界存在的同名變量,在該作用域下,該變量在變量聲明之前都不能被使用。


變量聲明結(jié)論

var:

存在變量提升,可重復(fù)多次聲明同名變量。

let:

不存在變量提升,必須先定義再使用,否則報錯;

同一作用域下不可重復(fù)定義同名變量,否則報錯;

在代碼塊內(nèi),通過let聲明的變量,盡管代碼塊外層有同名變量,代碼塊內(nèi)部在該變量聲明前都不能使用該變量,否則報錯。

const:

不存在變量提升,必須先定義再使用,否則報錯;

同一作用域下不可重復(fù)定義同名變量,否則報錯;

創(chuàng)建變量的同時必須對其賦值,且賦值后不能直接通過=直接替換整個值否則報錯;

在代碼塊內(nèi),通過const聲明的變量,盡管代碼塊外層有同名變量,代碼塊內(nèi)部在該變量聲明前都不能使用該變量,否則報錯。

letconst的出現(xiàn),很好地把ES5中var定義變量的Bug給埋了,解決了定義同名變量導(dǎo)致變量間相互污染的問題,保證了同一塊級作用域下,變量名的唯一性。同時const定義常量能更直觀地明白常量的意義及其不可修改性。


塊級作用域

ES6新增的變量聲明命令存在塊級作用域

什么是塊級作用域?
{
    var a = "test";
    let b = "test1";
}
console.log(a);     //test
console.log(b);     //Uncaught ReferenceError: b is not defined

這便是塊級作用域最基本的示例,通過let、const聲明的變量僅能在其代碼塊內(nèi)被使用,該代碼塊內(nèi)部即是一個塊級作用域

塊級作用域有什么用?
var a = "test";
function f(){
    console.log(a);
    if(true) {
        var a = "test1";
    }
    console.log(a);
}
f();        //undefinded   test1

這個例子輸出的結(jié)果是undefined,原因在于,在f()中,不論if語句判斷是否通過,if內(nèi)部的var a都被變量提升,且變量a均通過var命令聲明,內(nèi)部變量a覆蓋了外部變量a;

換個寫法再來一遍

let a = "test";
function f(){
    console.log(a);
    if(true) {
        let a = "test1";
    }
    console.log(a);
}
f();        //test   test

比對一下兩段代碼的執(zhí)行情況:
看看該代碼的實際執(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是另一個a,可以理解為_a,且_a的作用范圍僅在if語句內(nèi)
a = "test1"                         a = "test1";    //類似于_a = "test1"
console.log(a)                      console.log(a)  //類似于console.log(_a)

從上面的比對可以看出,通過let聲明的變量a,不會被變量提升,且具有塊級作用域,不會影響到上層作用域的a變量

再來一個示例:

for(var i=0;i<10;i++){
    console.log("for里面的i:"+i);          // 1、2、3......10
}
console.log(i);            //10

這里定義的循環(huán)計數(shù)變量i,原本只是想在循環(huán)內(nèi)使用,但由于使用了var聲明,因此不存在塊級作用域,導(dǎo)致for循環(huán)外也能獲取到了i的值。

ES6中規(guī)定,函數(shù)本身的作用域在其所在的塊級作用域當(dāng)中。

function fn() {
    console.log("outside console");
}
(function() {
    if(false) {
        function fn() {
            console.log("inside console");
        }
    }
    fn();
}());

上述代碼中,fn()執(zhí)行結(jié)果會報錯fn is not a function,因為在fn執(zhí)行的環(huán)境中存在function fn的聲明,聲明被提前,導(dǎo)致fn被提前定義,但沒有被賦值為function。

ES6的函數(shù)自執(zhí)行代碼變得精簡。

//從
(function() {
    console.log("test");
})();

//變?yōu)?
{
    console.log("test");
}
塊級作用域結(jié)論

通過使用let const,讓變量存在了塊級作用域,很好地劃分變量間的作用范圍,避免了以往同名變量相互污染問題;外層變量無法直接讀取內(nèi)層變量,對內(nèi)層變量具有更好的保密性,內(nèi)外層代碼獨立執(zhí)行,相互間不影響;精簡了函數(shù)自執(zhí)行代碼

以上。

文章觀點內(nèi)容如有錯誤歡迎指出交流,相互進步

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/104167.html

相關(guān)文章

  • Javascript ES6學(xué)習(xí)

    摘要:以下簡稱是語言的下一代標準。因為當(dāng)前版本的是在年發(fā)布的,所以又稱。命令用于規(guī)定模塊的對外接口,命令用于輸入其他模塊提供的功能。需要特別注意的是,命令規(guī)定的是對外的接口,必須與模塊內(nèi)部的變量建立一一對應(yīng)關(guān)系。 ECMAScript 6(以下簡稱ES6)是JavaScript語言的下一代標準。因為當(dāng)前版本的ES6是在2015年發(fā)布的,所以又稱ECMAScript 2015。 最常用的ES6...

    gclove 評論0 收藏0
  • JavaScript基礎(chǔ)系列---變量及其值類型

    摘要:但對于引用類型的數(shù)據(jù)主要是對象和數(shù)組,變量指向的內(nèi)存地址,保存的只是一個引用地址指針,只能保證這個引用地址指針是固定的,至于它指向的堆內(nèi)存中的存儲的值是不是可變的,就完全不能控制了。 基礎(chǔ)概念 變量是存儲信息的容器,這里需要區(qū)分一下:變量不是指存儲的信息本身,而是指這個用于存儲信息的容器,可以把變量想象成一個個用來裝東西的紙箱子 變量需要聲明,并且建議在聲明的同時進行初始化,如下所...

    sugarmo 評論0 收藏0
  • 30分鐘掌握ES6/ES2015核心內(nèi)容

    摘要:以下簡稱是語言的下一代標準。因為當(dāng)前版本的是在年發(fā)布的,所以又稱。用它所聲明的變量,只在命令所在的代碼塊內(nèi)有效。的繼承機制,實質(zhì)是先創(chuàng)造父類的實例對象所以必須先調(diào)用方法,然后再用子類的構(gòu)造函數(shù)修改。 ECMAScript 6(以下簡稱ES6)是JavaScript語言的下一代標準。因為當(dāng)前版本的ES6是在2015年發(fā)布的,所以又稱ECMAScript 2015。 也就是說,ES6就是E...

    LucasTwilight 評論0 收藏0
  • 30分鐘掌握ES6/ES2015核心內(nèi)容(上)

    摘要:以下簡稱是語言的下一代標準。的繼承機制,實質(zhì)是先創(chuàng)造父類的實例對象所以必須先調(diào)用方法,然后再用子類的構(gòu)造函數(shù)修改。總結(jié)以上就是最常用的一些語法,可以說這的語法,在的日常使用中占了追加十分鐘好的嗎分鐘掌握核心內(nèi)容下 ECMAScript 6(以下簡稱ES6)是JavaScript語言的下一代標準。因為當(dāng)前版本的ES6是在2015年發(fā)布的,所以又稱ECMAScript 2015。 也就是說...

    YPHP 評論0 收藏0
  • es6語法快速上手

    摘要:二一個的解析器在我們正式講解語法之前,我們得先了解下。而則實際上為新增了塊級作用域。的繼承機制,實質(zhì)是先創(chuàng)造父類的實例對象所以必須先調(diào)用方法,然后再用子類的構(gòu)造函數(shù)修改。 隨著google和firfox以及node6.0對es6的支持,es6語法的定稿使它越來越受到關(guān)注,尤其是react項目基本上都是用es6來寫的。是時候從es5到es6轉(zhuǎn)變了showImg(http://static...

    PiscesYE 評論0 收藏0

發(fā)表評論

0條評論

Olivia

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<