亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

es6塊級(jí)綁定之let and const全理解

TigerChain / 644人閱讀

摘要:聲明會(huì)組織對(duì)變量綁定和對(duì)自生值的修改,這意味著聲明并不會(huì)組織對(duì)變量成員的修改。循環(huán)中的塊級(jí)綁定在此處仍然可被訪問輸出的結(jié)果并不是預(yù)期的值而是是因?yàn)槁暶鲗?dǎo)致的變量的提升。全局塊級(jí)綁定與不同于的另一個(gè)方面是在全局作用域上的表現(xiàn)。

變量聲明一直是js工作中最微妙的一部分,它不像C語(yǔ)言一樣,變量總是在被它創(chuàng)建的時(shí)候聲明,js語(yǔ)言可以允許你在你需要聲明變量的時(shí)候進(jìn)行聲明。

var let const 之變量聲明

var 聲明與變量提升。

當(dāng)我們使用var關(guān)鍵字進(jìn)行變量聲明的時(shí)候,無(wú)論變量聲明的位置在哪里,都會(huì)被是為聲明于所在的函數(shù)的頂部(如果不在函數(shù)內(nèi)的話,則視為在全局作用域的頂部)這就是所謂的變量提升(hoisting)

var提升如下:

function getValue(condition) {
if (condition) {
var value = "blue";
// 其他代碼
return value;
} else {
// value 在此處可訪問,值為 undefined
return null;
}
// value 在此處可訪問,值為 undefined
}

塊級(jí)聲明let

塊級(jí)聲明也就是讓所聲明的變量在指定的作用域外無(wú)法被訪問到,塊級(jí)作用域在如下情況下被創(chuàng)建

在一個(gè)函數(shù)內(nèi)部,

在一個(gè)代碼塊(由一對(duì)花括號(hào)包裹)內(nèi)部

let聲明的語(yǔ)法和var聲明一致,由于let聲明不會(huì)將變量提升到函數(shù)頂部,因此我們需要手動(dòng)將let聲明放置到頂部,以便讓變量在整個(gè)代碼塊內(nèi)部可用。

如下所示:

function getValue(condition) {
if (condition) {
let value = "blue";
// 其他代碼
return value;
} else {
// value 在此處不可用
return null;
}
// value 在此處不可用
}
禁止重復(fù)標(biāo)識(shí)

如果一個(gè)標(biāo)識(shí)符已經(jīng)在代碼內(nèi)部被定義,重復(fù)進(jìn)行l(wèi)et聲明會(huì)報(bào)錯(cuò)

var a = 30;
//報(bào)錯(cuò)
let a = 30;
a變量被聲明了兩次:一次使用 var ,另一次使用 let 。因?yàn)?let 不能在同一作用域內(nèi)重復(fù)聲明一個(gè)已有標(biāo)識(shí)符,此處的 let 聲明就會(huì)拋出錯(cuò)誤。另一方面,在嵌套的作用域內(nèi)使用 let 聲明一個(gè)同名的新變量,則不會(huì)拋出錯(cuò)誤,以下代碼對(duì)此進(jìn)行了演示:
var count = 30;
// 不會(huì)拋出錯(cuò)誤
if (condition) {
let count = 40;
// 其他代碼
}
這段代碼中不會(huì)拋錯(cuò),關(guān)鍵點(diǎn)在于let在同一級(jí)代碼塊中重復(fù)聲明會(huì)報(bào)錯(cuò) const常量聲明 在es6中可以使用const語(yǔ)法進(jìn)行聲明。使用const聲明的變量會(huì)被認(rèn)為是常量(constant),意味著他們的值在被設(shè)置完成后既不能再被改變。正因?yàn)槿绱耍械腸onst的變量都需要在聲明時(shí)進(jìn)行初始化,
// 有效的常量
const maxItems = 30;
// 語(yǔ)法錯(cuò)誤:未進(jìn)行初始化
const name;
maxItems 變量被初始化了,因此它的 const 聲明能正常起效。而 name 變量沒有被初始化,導(dǎo)致在試圖運(yùn)行這段代碼時(shí)拋出了錯(cuò)誤。const聲明會(huì)組織對(duì)變量綁定和對(duì)自生值的修改,這意味著const聲明并不會(huì)組織對(duì)變量成員的修改。例如:
const person = {
name: "Nicholas"
};
// 工作正常
person.name = "Greg";
// 拋出錯(cuò)誤
person = {
name: "Greg"
};
const聲明和let聲明的對(duì)比

首先他們都是塊級(jí)聲明,這就意味著常量在聲明它們的語(yǔ)句塊外是無(wú)法被訪問的,并且聲明也不會(huì)被提升,示例如下:

if (condition) {
const maxItems = 5;
// 其他代碼
}
// maxItems 在此處無(wú)法訪問

它們?cè)诮y(tǒng)一級(jí)作用域中重復(fù)聲明時(shí)會(huì)導(dǎo)致拋出錯(cuò)誤

暫時(shí)性死區(qū) 當(dāng)我們使用let或者const 進(jìn)行聲明的時(shí)候,在到達(dá)聲明處之前都是無(wú)法訪問的,如果我們?cè)噲D訪問會(huì)導(dǎo)致一個(gè)引用錯(cuò)誤。出項(xiàng)這個(gè)問題是因?yàn)闀簳r(shí)性死區(qū) 當(dāng)JS 引擎檢視接下來(lái)的代碼塊并發(fā)現(xiàn)變量聲明時(shí),它會(huì)在面對(duì) var 的情況下將聲明提升到函數(shù)或全局作用域的頂部,而面對(duì) let 或 const 時(shí)會(huì)將聲明放在暫時(shí)性死區(qū)內(nèi)。任何在暫時(shí)性死區(qū)內(nèi)訪問變量的企圖都會(huì)導(dǎo)致“運(yùn)行時(shí)”錯(cuò)誤(runtime error)。只有執(zhí)行到變量的聲明語(yǔ)句時(shí),該變量才會(huì)從暫時(shí)性死區(qū)內(nèi)被移除并可以安全使用。 循環(huán)中的塊級(jí)綁定
for (var i = 0; i < 10; i++) {
process(items[i]);
}
// i 在此處仍然可被訪問
console.log(i); // 10

輸出的結(jié)果并不是預(yù)期的值而是10;是因?yàn)関ar聲明導(dǎo)致的變量的提升。聰明的你肯定會(huì)想到使用塊級(jí)綁定來(lái)進(jìn)行變量聲明

for (let i = 0; i < 10; i++) {
process(items[i]);
}

console.log(i);

i在此處是不是會(huì)正常輸出呢,其實(shí)不會(huì),在這個(gè)例子中會(huì)導(dǎo)致報(bào)錯(cuò),為什么呢?因?yàn)閕在此處不可訪問。本例中的變量 i 僅在 for 循環(huán)內(nèi)部可用,一旦循環(huán)結(jié)束,該變量在任意位置都不可訪問。

我們?cè)趤?lái)看看一下代碼

var funcs = [];
for (var i = 0; i < 10; i++) {
funcs.push(function() { console.log(i); });
}
funcs.forEach(function(func) {
func(); // 輸出數(shù)值 "10" 十次
});

你原本可能預(yù)期這段代碼會(huì)輸出 0 到 9 的數(shù)值,但它卻在同一行將數(shù)值 10 輸出了十次。這是
因?yàn)樽兞?i 在循環(huán)的每次迭代中都被共享了,意味著循環(huán)內(nèi)創(chuàng)建的那些函數(shù)都擁有對(duì)于同一
變量的引用。在循環(huán)結(jié)束后,變量 i 的值會(huì)是 10 ,因此當(dāng) console.log(i) 被調(diào)用時(shí),
每次都打印出 10 。

為了修正這個(gè)問題,開發(fā)者在循環(huán)內(nèi)使用立即調(diào)用函數(shù)表達(dá)式(IIFEs),以便在每次迭代中
強(qiáng)制創(chuàng)建變量的一個(gè)新副本,示例如下:

var funcs = [];
for (var i = 0; i < 10; i++) {
funcs.push((function(value) {
return function() {
console.log(value);
}
}(i)));
}
funcs.forEach(function(func) {
func(); // 從 0 到 9 依次輸出
});
循環(huán)內(nèi)的 let 聲明

let 聲明通過有效模仿上例中 IIFE 的作用而簡(jiǎn)化了循環(huán)。在每次迭代中,都會(huì)創(chuàng)建一個(gè)新的
同名變量并對(duì)其進(jìn)行初始化。這意味著你可以完全省略 IIFE 而獲得預(yù)期的結(jié)果,就像這樣

var funcs = [];
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i);
});
}
funcs.forEach(function(func) {
func(); // 從 0 到 9 依次輸出
})

我們是否會(huì)想到這個(gè)問題:為什么同樣的代碼使用let聲明會(huì)導(dǎo)致不一樣的結(jié)果呢?
在循環(huán)中l(wèi)et聲明每次都創(chuàng)建了一個(gè)新的i變量,因此在循環(huán)內(nèi)部創(chuàng)建的函數(shù)獲得了各自的i副本,而每個(gè)i副本的值都會(huì)在每次的循環(huán)迭代聲明變量的時(shí)候確定了

var funcs = [],
object = {
a: true,
b: true,
c: true
};
for (let key in object) {
funcs.push(function() {
console.log(key);
});
}
funcs.forEach(function(func) {
func(); // 依次輸出 "a"、 "b"、 "c"
});

本例中的 for-in 循環(huán)體現(xiàn)出了與 for 循環(huán)相同的行為。每次循環(huán),一個(gè)新的 key 變量綁
定就被創(chuàng)建,因此每個(gè)函數(shù)都能夠擁有它自身的 key 變量副本,結(jié)果每個(gè)函數(shù)都輸出了一個(gè)
不同的值。而如果使用 var 來(lái)聲明 key ,則所有函數(shù)都只會(huì)輸出 "c" 。
let 聲明在循環(huán)內(nèi)部的行為是在規(guī)范中特別定義的,而與不提升變
量聲明的特征沒有必然聯(lián)系。事實(shí)上,在早期 let 的實(shí)現(xiàn)中并沒有這種行為,它是后來(lái)
才添加的。

循環(huán)內(nèi)的常量聲明

雖然es6沒有明確的規(guī)范我們不能在for循環(huán)中使用const聲明,然而它會(huì)根據(jù)循環(huán)方式的不同而有不同的行為,我們可以在初始化時(shí)使用const,但是當(dāng)循環(huán)試圖改變變量的值的時(shí)候會(huì)拋出錯(cuò)誤,例如:

var funcs = [];
// 在一次迭代后拋出錯(cuò)誤
for (const i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i);
});
}

在此代碼中, i 被聲明為一個(gè)常量。循環(huán)的第一次迭代成功執(zhí)行,此時(shí) i 的值為 0 。在
i++ 執(zhí)行時(shí),一個(gè)錯(cuò)誤會(huì)被拋出,因?yàn)樵撜Z(yǔ)句試圖更改常量的值。因此,在循環(huán)中你只能使
用 const 來(lái)聲明一個(gè)不會(huì)被更改的變量
而另一方面, const 變量在 for-in 或 for-of 循環(huán)中使用時(shí),與 let 變量效果相同。因
此下面代碼不會(huì)導(dǎo)致出錯(cuò):

var funcs = [],
object = {
a: true,
b: true,
c: true
};
// 不會(huì)導(dǎo)致錯(cuò)誤
for (const key in object) {
funcs.push(function() {
console.log(key);
});
}
funcs.forEach(function(func) {
func(); // 依次輸出 "a"、 "b"、 "c"
});

這段代碼與“循環(huán)內(nèi)的 let 聲明”小節(jié)的第二個(gè)例子幾乎完全一樣,唯一的區(qū)別是 key 的值在
循環(huán)內(nèi)不能被更改。 const 能夠在 for-in 與 for-of 循環(huán)內(nèi)工作,是因?yàn)檠h(huán)為每次迭
代創(chuàng)建了一個(gè)新的變量綁定,而不是試圖去修改已綁定的變量的值(就像使用了 for 而不是
for-in 的上個(gè)例子那樣)。

全局塊級(jí)綁定
let 與 const 不同于 var 的另一個(gè)方面是在全局作用域上的表現(xiàn)。當(dāng)在全局作用域上使
用 var 時(shí),它會(huì)創(chuàng)建一個(gè)新的全局變量,并成為全局對(duì)象(在瀏覽器中是 window )的一
個(gè)屬性。
總結(jié) let和const塊級(jí)作用域的引入,能夠使我們減少很多無(wú)心的錯(cuò)誤,它們的一個(gè)副作用,是不能在變量聲明位置之前訪問它們 塊級(jí)綁定當(dāng)前的最佳實(shí)踐就是:在默認(rèn)情況下使用 const ,而只在你知道變量值需要被更改的情況下才使用 let 。這在代碼中能確?;緦哟蔚牟豢勺冃?,有助于防止某些類型的錯(cuò)誤。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/103124.html

相關(guān)文章

  • 深入理解ES6塊級(jí)作用域綁定

    摘要:眾所周知,中的聲明存在變量提升機(jī)制,因此引用了塊級(jí)作用域來(lái)強(qiáng)化對(duì)變量生命周期的控制聲明不會(huì)被提升,有幾個(gè)需要注意的點(diǎn)不能被重復(fù)聲明假設(shè)作用域中已經(jīng)存在某個(gè)標(biāo)識(shí)符無(wú)論該標(biāo)識(shí)符是通過聲明還是變量聲明,此時(shí)再使用或關(guān)鍵定聲明會(huì)拋錯(cuò)此處則會(huì)拋出錯(cuò)誤 眾所周知,js中的var聲明存在變量提升機(jī)制,因此ESMAScript 6引用了塊級(jí)作用域來(lái)強(qiáng)化對(duì)變量生命周期的控制let const 聲明不會(huì)被...

    Nosee 評(píng)論0 收藏0
  • 深入理解ES6 - var-let-const

    摘要:聲明變量不存在變量提升。臨時(shí)死區(qū),而且不能在聲明之前訪問它。禁止重復(fù)聲明相同的變量,否則報(bào)錯(cuò)。不存在變量提升,一旦執(zhí)行快外就會(huì)立即銷毀。聲明不允許修改綁定,但允許修改值,也就是說用創(chuàng)建對(duì)象后,可以修改該對(duì)象的屬性值。 知識(shí)點(diǎn) var 聲明變量: 1、存在變量提升,實(shí)際上var無(wú)論在哪里聲明,都會(huì)被當(dāng)做當(dāng)前的作用域頂部聲明變量。 2、可以重復(fù)聲明,后聲明的變量會(huì)覆蓋前聲明的變量。 let...

    alexnevsky 評(píng)論0 收藏0
  • ES6 系列 letconst

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

    PascalXie 評(píng)論0 收藏0
  • let,const與var的比較

    摘要:聲明一個(gè)只讀的常量。的作用域與命令相同只在聲明所在的塊級(jí)作用域內(nèi)有效。這在語(yǔ)法上,稱為暫時(shí)性死區(qū),簡(jiǎn)稱。暫時(shí)性死區(qū)也意味著不再是一個(gè)百分之百安全的操作。重復(fù)聲明是允許在相同作用域內(nèi)重復(fù)聲明同一個(gè)變量的,而與不允許這一現(xiàn)象。 轉(zhuǎn)載自阮一峰老師的ES6入門,稍有修改 1.基本概念MDN var聲明了一個(gè)變量,并且可以同時(shí)初始化該變量。let語(yǔ)句聲明一個(gè)塊級(jí)作用域的本地變量,并且可選的賦予...

    lemon 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<