国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

Javascript基礎(chǔ)之-var,let和const深入解析(二)

XiNGRZ / 1461人閱讀

摘要:規(guī)范對(duì)其是這樣進(jìn)行的描述的。聲明定義了在正在運(yùn)行的執(zhí)行上下文作用域內(nèi)的變量環(huán)境中的變量。在執(zhí)行時(shí),由帶有的定義的變量被賦其設(shè)定項(xiàng)的的值。由于變量已經(jīng)被聲明,是可訪問(wèn)的,因此會(huì)打印出正確的結(jié)果。

你想在在變量聲明之前就使用變量?以后再也別這樣做了。

新的聲明方式(let,const)較之之前的聲明方式(var),還有一個(gè)區(qū)別,就是新的方式不允許在變量聲明之前就使用該變量,但是var是可以得。請(qǐng)看下面的代碼,下面這個(gè)代碼是可以正常運(yùn)行的:

function func() {
  console.log(localVariable);   // undefined
  var localVariable = 5;

  console.log(localVariable);   // 5
}

func();

但是這種卻不可以

function func() {
  console.log(localVariable); // ReferenceError: localVariable is not defined
  let localVariable = 10;

  console.log(localVariable); // 10
}

func();

等下,我們上一章曾經(jīng)介紹了一個(gè)叫“提升”的概念,它會(huì)吧所有的變量定義在作用域的最前面。這是否意味著如果我不在實(shí)際的定義之前使用變量,然后就不會(huì)有提升了呢?答案是否定的。提升依然會(huì)有,并且適用于所有類(lèi)型的變量類(lèi)型。但是const和let卻不是這樣的。

首先,我們看一下var關(guān)鍵字是怎么工作的。規(guī)范對(duì)其是這樣進(jìn)行的描述的。

var聲明定義了在正在運(yùn)行的執(zhí)行上下文(running execution
context)作用域內(nèi)的變量環(huán)境(VariableEnvironment中)的變量。var變量在當(dāng)包含的詞法環(huán)境(Lexical
Environment)初始化時(shí)被創(chuàng)建,在創(chuàng)建的時(shí)候被賦值為undefined。[...]
在執(zhí)行VariableDeclaration時(shí),由帶有Initializer的VariableDeclaration定義的變量被賦其設(shè)定項(xiàng)的Initializer"s
AssignmentExpression的值。

規(guī)范中有許多的細(xì)節(jié),讓我們簡(jiǎn)單的來(lái)看一下:

當(dāng)你進(jìn)入到一個(gè)作用域中,在內(nèi)部被定義的所有的變量都會(huì)被創(chuàng)建。

所有存在的變量,都可以被訪問(wèn),并且會(huì)把undefined賦值給該變量。

當(dāng)代碼(執(zhí)行時(shí))到達(dá)初始化時(shí),會(huì)被分配給一個(gè)實(shí)際的值。

我們來(lái)看一下規(guī)范中對(duì)let和const的表述:

let和const聲明是定義在當(dāng)前執(zhí)行上下文作用域中的詞法環(huán)境中的變量。當(dāng)包含的詞法環(huán)境被初始化的時(shí)候,變量被創(chuàng)建。但是在變量的詞法綁定時(shí)被計(jì)算之前是不允許通過(guò)任何方式來(lái)訪問(wèn)的。當(dāng)詞法綁定計(jì)算時(shí)而不是在變量被創(chuàng)建的時(shí)候,由詞法綁定定義的變量的初始值被被賦予賦值表達(dá)式的值(也就是“=”右邊的表達(dá)式)。當(dāng)詞法綁定被計(jì)算的時(shí)候,如果let聲明中沒(méi)有初始化的值的時(shí)候(也就是“l(fā)et
a;”這樣的形式),會(huì)被賦值為undefined。

簡(jiǎn)單來(lái)說(shuō):

如果你進(jìn)入到了指定的作用域中,它里面定義的所有的變量都會(huì)被初始化,這一點(diǎn)和var很像。

這里有一個(gè)不同點(diǎn):像var一樣,所有的變量都會(huì)存在,但是他們目前還不能被訪問(wèn)(里面沒(méi)有值,甚至是undefined)。

如果let變量在相同的地方被定義和初始化,他們會(huì)被賦予合適的值,反之,變量就是undefined。const變量必須在定義的時(shí)候初始化。

我們來(lái)看一些相關(guān)的例子。

臨時(shí)死區(qū)

實(shí)際上,這種描述引出了我們的另一個(gè)定義。他很讓人可怕,因?yàn)樗校号R時(shí)死區(qū)(TDZ)。這個(gè)屬于明確了一個(gè)我們無(wú)法訪問(wèn)我們的變量的代碼的區(qū)域。我們來(lái)看一下下面的代碼和相關(guān)聯(lián)的注釋?zhuān)瑏?lái)簡(jiǎn)單的解釋一下TDZ是什么。

function func() {
  // Start of TDZ for deadVariable
  // we can still do something here, just our deadVariable is not available yet
  const exampleVariable = 5;
  console.log(exampleVariable); // 5
  // End of TDZ for deadVariable
  let deadVariable = 10;

  console.log(deadVariable);  // 10
}

func();

有一件事情值得去提醒。就是對(duì)于名字的建議,這是一個(gè)臨時(shí)死區(qū),意思這個(gè)區(qū)域是由時(shí)間定義的,而不是位置。因此當(dāng)運(yùn)行代碼的時(shí)候,你的聲明在被JS解析器解析之前是不能被訪問(wèn)的。因此你把使用的變量的位置放在哪里并不重要,只要是在聲明執(zhí)行后訪問(wèn)該變量就可以。所以看下面的代碼:

function func() {
  return deadOrAlive;
}

let deadOrAlive = "alive!"
console.log(func());  // alive!

這是運(yùn)行代碼的步驟:

函數(shù)被聲明

變量deadOrAlive被聲明,并且初始化了一個(gè)值“alive”

現(xiàn)在我們調(diào)用我們的函數(shù)。

由于變量deadOrAlive已經(jīng)被聲明,是可訪問(wèn)的,因此會(huì)打印出正確的結(jié)果 “alive”。

但是下面的例子卻會(huì)報(bào)錯(cuò),思考一下原因。

function func() {
  return deadOrAlive;
}

console.log(func());  // ReferenceError: deadOrAlive is not defined
let deadOrAlive = "dead!"

所以TDZ是一個(gè)避免因先使用后聲明而導(dǎo)致的一些詭異的bug而出現(xiàn)的一個(gè)很好機(jī)制(具體看“提升”相關(guān)內(nèi)容)。我們不需要去額外做什么事情,就是記住永遠(yuǎn)不要在變量聲明之前使用這個(gè)變量。即使我們這樣做了,我們也會(huì)得到一個(gè)很好的報(bào)錯(cuò)信息。只有一個(gè)條件-你必須使用let或者是const來(lái)替換掉var。

雙定義

var和let,const的另一個(gè)區(qū)別是 - 后者僅僅可以被定義一次。而對(duì)于var的話,如果被同時(shí)定義多次,程序也依然會(huì)很好的運(yùn)行。

var doubledVariable = 5;
var doubledVariable = 6;

console.log(doubledVariable); // 6

但是現(xiàn)在,當(dāng)你用let和const來(lái)做同樣的事情,就會(huì)得到一個(gè)語(yǔ)法錯(cuò)誤:

let doubledVariable = 5;
let doubledVariable = 6;  // SyntaxError: Identifier "doubledVariable" has already been declared

但是,在嵌套的塊級(jí)作用域中,使用相同名字的變量依然會(huì)很好的工作的,這個(gè)我想大家已經(jīng)清楚了,就不用過(guò)多解釋了吧。

let doubledVariable = 5;

if (true) {
  let doubledVariable = 6;
  console.log(doubledVariable); // 6
}

console.log(doubledVariable); // 5

不能重復(fù)定義這個(gè)功能實(shí)際上是很有用的,可以組織很多bug的發(fā)生。比如說(shuō)你曾經(jīng)在一個(gè)函數(shù)內(nèi),在不同地方用var定義了多個(gè)相同名稱(chēng)的變量,此時(shí)之前定義的變量可能會(huì)被覆蓋,這樣對(duì)于代碼來(lái)說(shuō)無(wú)疑是一個(gè)隱患,也就是因?yàn)檫@樣,這個(gè)特性實(shí)際上是一個(gè)簡(jiǎn)單的,開(kāi)箱即用的解決方案。

總結(jié)

總結(jié)一下,在ES6中有兩種新方法來(lái)聲明變量:通過(guò)let和const關(guān)鍵字,除此之外,兩者都是塊級(jí)作用域,并且在聲明之前不能訪問(wèn)該變量。與之前的var相比是一個(gè)主要的升級(jí)。并且會(huì)消除你很多的困擾。我提出了幾個(gè)例子,可能會(huì)幫助你節(jié)省了不少調(diào)試的時(shí)間,但是還有更多。如果你感興趣的話,可以在網(wǎng)上簡(jiǎn)單的搜索一下。很久之前,我個(gè)人曾建議停止使用var關(guān)鍵字,所以現(xiàn)在我的代碼里充滿了let和const。我建議你也是這樣,在以后當(dāng)你想改變變量的值,就使用let和const。不要再使用var了。

本文翻譯自:

https://blog.pragmatists.com/...

本文轉(zhuǎn)載自:http://www.lht.ren/article/16/

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/101729.html

相關(guān)文章

  • 【進(jìn)階1-4期】JavaScript深入帶你走進(jìn)內(nèi)存機(jī)制

    摘要:引擎對(duì)堆內(nèi)存中的對(duì)象進(jìn)行分代管理新生代存活周期較短的對(duì)象,如臨時(shí)變量字符串等。內(nèi)存泄漏對(duì)于持續(xù)運(yùn)行的服務(wù)進(jìn)程,必須及時(shí)釋放不再用到的內(nèi)存。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開(kāi)始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第4天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)劃...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • JavaScript 進(jìn)階深入理解數(shù)據(jù)雙向綁定

    摘要:當(dāng)我們的視圖和數(shù)據(jù)任何一方發(fā)生變化的時(shí)候,我們希望能夠通知對(duì)方也更新,這就是所謂的數(shù)據(jù)雙向綁定。返回值返回傳入函數(shù)的對(duì)象,即第一個(gè)參數(shù)該方法重點(diǎn)是描述,對(duì)象里目前存在的屬性描述符有兩種主要形式數(shù)據(jù)描述符和存取描述符。 前言 談起當(dāng)前前端最熱門(mén)的 js 框架,必少不了 Vue、React、Angular,對(duì)于大多數(shù)人來(lái)說(shuō),我們更多的是在使用框架,對(duì)于框架解決痛點(diǎn)背后使用的基本原理往往關(guān)注...

    sarva 評(píng)論0 收藏0
  • 【進(jìn)階1-1期】理解JavaScript 中的執(zhí)行上下文執(zhí)行棧

    摘要:首次運(yùn)行代碼時(shí),會(huì)創(chuàng)建一個(gè)全局執(zhí)行上下文并到當(dāng)前的執(zhí)行棧中。執(zhí)行上下文的創(chuàng)建執(zhí)行上下文分兩個(gè)階段創(chuàng)建創(chuàng)建階段執(zhí)行階段創(chuàng)建階段確定的值,也被稱(chēng)為。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開(kāi)始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,,今天是第一天 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)...

    import. 評(píng)論0 收藏0
  • 【進(jìn)階2-3期】JavaScript深入閉包面試題解

    摘要:閉包面試題解由于作用域鏈機(jī)制的影響,閉包只能取得內(nèi)部函數(shù)的最后一個(gè)值,這引起的一個(gè)副作用就是如果內(nèi)部函數(shù)在一個(gè)循環(huán)中,那么變量的值始終為最后一個(gè)值。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開(kāi)始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第8天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了...

    alanoddsoff 評(píng)論0 收藏0
  • 深入了解babel(

    摘要:接著上一篇文章深入了解一的處理步驟的三個(gè)主要處理步驟分別是解析,轉(zhuǎn)換,生成。模塊是的代碼生成器,它讀取并將其轉(zhuǎn)換為代碼和源碼映射抽象語(yǔ)法樹(shù)抽象語(yǔ)法樹(shù)在以上三個(gè)神器中都出現(xiàn)過(guò),所以對(duì)于編譯器來(lái)說(shuō)至關(guān)重要。 接著上一篇文章《深入了解babel(一)》 Babel 的處理步驟 Babel 的三個(gè)主要處理步驟分別是: 解析(parse),轉(zhuǎn)換(transform),生成(generate)。對(duì)...

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

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

0條評(píng)論

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