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

資訊專欄INFORMATION COLUMN

【ES6系列】變量與塊級作用域

PascalXie / 2611人閱讀

摘要:不允許在相同作用域內(nèi),重復聲明同一個變量。如但是在中則不再必要了,我們可以通過塊級作用域就能夠?qū)崿F(xiàn)本次主要針對中的變量和塊級作用域進行了梳理學習,并且通過與的實現(xiàn)方式進行了對比,從而看出其變化以及快捷與便利。

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

ES6的出現(xiàn)已經(jīng)很久了,由于之前的項目只是基于ES5以及之前的版本內(nèi)容進行開發(fā)的,所以沒有系統(tǒng)性的梳理學習ES6的相關(guān)知識。感覺自己已經(jīng)被發(fā)展的車輪落下了好遠好遠(@﹏@)~,所以在接下來這段時間針對性的進行學習整理,希望能夠讓自己有所提高,也希望能幫助和我一樣的人……

變量 常量 const命令 常量的定義

在之前的版本ES5甚至更早的版本(后面統(tǒng)稱ES5)中,很少能夠聽到常量的概念,我們也知道,JS不同于其他的語言,如Java、C++等,有常量的概念。雖然通過其他的方法能夠達到實現(xiàn)常量的方法,但是并不直接、方便。

如可通過下述方式進行常量的實現(xiàn):

// 此處在window對象上面定義了一個圓周率變量PI,使之不能被修改,模擬常量
Object.defineProperty(window, "PI", {
    value: 3.1415926,
    writable: false
})

在ES6中,定義一個常量則非常簡單,通過const進行聲明即可。

const聲明一個只讀的常量。一旦聲明,常量的值就不能改變。
const PI = 3.1415926;

const聲明的變量不得改變值,這意味著,const一旦聲明變量,就必須立即初始化,不能留到以后賦值。

const定義常量的本質(zhì)

const實際上保證的,并不是變量的值不得改動,而是變量指向的那個內(nèi)存地址不得改動。對于簡單類型的數(shù)據(jù)(數(shù)值、字符串、布爾值),值就保存在變量指向的那個內(nèi)存地址,因此等同于常量。但對于復合類型的數(shù)據(jù)(主要是對象和數(shù)組),變量指向的內(nèi)存地址,保存的只是一個指針,const只能保證這個指針是固定的,至于它指向的數(shù)據(jù)結(jié)構(gòu)是不是可變的,就完全不能控制了。

如:

const foo = {};

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

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

在ES6中新增了let命令,可以用來聲明一個變量,作用類似于之前常用的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

通過上面代碼的執(zhí)行結(jié)果來看能夠看出,let聲明的變量只在它所在的代碼塊中有效,即{}所在的代碼塊內(nèi)。

那么let聲明的變量在什么情況下會比較有用呢?先讓我們來看下下面一段代碼:

var arrays = [];
for (var i = 0; i <= 2; i++) {
    arrays[i] = function() {
        return i * 2;
    }
}

console.table([
    arrays[0](),
    arrays[1](),
    arrays[2]()
])

可能我們預期的結(jié)果是顯示0,2,4,但是從執(zhí)行代碼的結(jié)果中能夠看出,得到的卻是6,6,6,這是為什么呢?
首先我們上面是使用的var聲明的一個i變量,此處會有一個變量提升,相當于在for循環(huán)外面聲明了var i = 0變量。當在for循環(huán)中時,arrays[i]中的i即為每次循環(huán)的i的值(0,1,2),但是在函數(shù)體中并沒有將i變量取值為每次循環(huán)的值,它只是對變量的一個引用,并不是值的引用。當在執(zhí)行循環(huán)中的函數(shù)體時,i變量已經(jīng)變成了3,所以每次的結(jié)構(gòu)輸出都是6。這個時候,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)時會將i變量的值保存在其對應的塊作用域中(for循環(huán)的{}),每一輪循環(huán)都是重新生成一個新的作用域,在執(zhí)行for循環(huán)中聲明的函數(shù)時,都會獲取其對應作用域內(nèi)的i的值。這部分涉及到的作用域相關(guān)的概念,我們后面會說到。

1、在前面提到過,var命令聲明的變量會發(fā)生變量提升的現(xiàn)象,即變量可以在聲明之前使用,值為undefined。按照一般的邏輯來說,變量應該在聲明語句之后才可以使用。所以在ES6中為了糾正這個現(xiàn)象,let命令改變了語法行為,它所聲明的變量一定要在聲明后使用,否則報錯。

2、只要在塊級作用域中存在let命令,它所聲明的變量就“綁定”(binding)這個區(qū)域,不再受外部的影響。

var tmp = 123;

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

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

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

3、typeof不再是一個完全安全的操作。之前我們知道,針對一個沒有生命的變量調(diào)用typeof方法時會返回undefined,但是在上面出現(xiàn)的“暫時性死區(qū)”中,typeof將會被報錯。

使用let聲明變量時,只要變量在還沒有聲明完成前使用,就會報錯。

4、let不允許在相同作用域內(nèi),重復聲明同一個變量。

塊級作用域 為什么需要塊級作用域

1、內(nèi)層變量可能會覆蓋外層變量

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = "hello world";
  }
}

f(); // undefined

內(nèi)層的tmp變量由于變量提升覆蓋了外層的tmp變量,導致輸出不符合預期

2、計數(shù)的循環(huán)變量泄露為全局變量

我們上面用到的for循環(huán)的例子就是這個現(xiàn)象的證明,var聲明的變量i在循環(huán)結(jié)束后泄露成了全局變量。

ES6的塊級作用域

在ES6中{}包裹的塊即為一個塊級作用域,并且塊級作用域支持嵌套,如

{{{{{let insane = "Hello World"}}}}}; // 5層塊級作用域

并且外層作用域不能讀取內(nèi)層作用域的變量;
內(nèi)層作用域可以定義外層作用域的同名變量。

在之前的版本中,當我們想要實現(xiàn)一個變量只在一個代碼塊中運行,我們往往需要通過使用立即執(zhí)行函數(shù)來實現(xiàn)。如

(function () {
  var tmp = ...;
  ...
}());

但是在ES6中則不再必要了,我們可以通過塊級作用域就能夠?qū)崿F(xiàn)

{
  let tmp = ...;
  ...
}
本次主要針對ES6中的變量和塊級作用域進行了梳理學習,并且通過與ES5的實現(xiàn)方式進行了對比,從而看出其變化以及快捷與便利。希望能夠?qū)δ兴鶐椭?,如有寫的不對的地方望請指正,從而共同進步。

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

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

相關(guān)文章

  • ES6 變量作用與提升:變量的生命周期詳解

    摘要:不同的是函數(shù)體并不會再被提升至函數(shù)作用域頭部,而僅會被提升到塊級作用域頭部避免全局變量在計算機編程中,全局變量指的是在所有作用域中都能訪問的變量。 ES6 變量作用域與提升:變量的生命周期詳解從屬于筆者的現(xiàn)代 JavaScript 開發(fā):語法基礎(chǔ)與實踐技巧系列文章。本文詳細討論了 JavaScript 中作用域、執(zhí)行上下文、不同作用域下變量提升與函數(shù)提升的表現(xiàn)、頂層對象以及如何避免創(chuàng)建...

    lmxdawn 評論0 收藏0
  • ES6系列文章 塊級作用

    摘要:聲明之函數(shù)作用域和全局作用域。塊級作用域不能重復聲明臨時性死區(qū)等特性用來解決變量存在的種種問題。塊級作用域終于在外面訪問不到了。一些常量聲明使用聲明的變量名全部大寫。 ES5之前javascript語言只有函數(shù)作用域和全局作用域,使用var來聲明變量,var聲明的變量還存在變量提升使人困惑不已。我們先來復習一下ES5的var聲明,再對比學習let和const 。 var var聲明之函...

    趙連江 評論0 收藏0
  • ES6學習總結(jié)(1)

    摘要:返回一個對象,遍歷對象自身和繼承的所有可枚舉屬性不含,與相同和在紅寶書中就已經(jīng)提到過屬性,表示的是引用類型實例的一個內(nèi)部指針,指向該實例的構(gòu)造函數(shù)的原型對象。 半個月前就決定要將ES6的學習總結(jié)一遍,結(jié)果拖延癥一犯,半個月就過去了,現(xiàn)在補起來,慚愧慚愧。 阮一峰的《ES6標準入門》這本書有300頁左右,除了幾個新的API和js語法的擴展,真正有價值的內(nèi)容并不多。所謂存在即合理,每部分的...

    happyfish 評論0 收藏0
  • ES6 系列之 let 和 const

    摘要:塊級作用域存在于函數(shù)內(nèi)部塊中字符和之間的區(qū)域和塊級聲明用于聲明在指定塊的作用域之外無法訪問的變量。和都是塊級聲明的一種。值得一提的是聲明不允許修改綁定,但允許修改值。這意味著當用聲明對象時沒有問題報錯臨時死區(qū)臨時死區(qū),簡寫為。 塊級作用域的出現(xiàn) 通過 var 聲明的變量存在變量提升的特性: if (condition) { var value = 1; } console.lo...

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

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

    sugarmo 評論0 收藏0

發(fā)表評論

0條評論

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