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

資訊專欄INFORMATION COLUMN

揭秘變量提升

lanffy / 2420人閱讀

摘要:想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳博客一年百來篇優(yōu)質(zhì)文章等著你引用規(guī)范作者一條最近的推特變量提升是一個(gè)陳舊且令人困惑的術(shù)語。變量提升部分提前激活是在和之前聲明變量的一種較老的方法。

為了保證可讀性,本文采用意譯而非直譯。

想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!

引用 ES6 規(guī)范作者 Allen Wirfs-Brock一條最近的推特:

變量提升是一個(gè)陳舊且令人困惑的術(shù)語。甚至在 ES6
之前:變量提升的意思究竟是“提升至當(dāng)前作用域頂部”還是“從嵌套的代碼塊中提升到最近的函數(shù)或腳本作用域中”?還是兩者都有?

受 Allen 啟發(fā),本文提出了一種不同的方法來描述變量聲明。

1. 聲明:作用域與激活

可以將聲明分為兩個(gè)方面:

作用域:在哪里可以看到聲明的變量? 這是一個(gè)靜態(tài)特征。

激活:我什么時(shí)候可以訪問變量? 這是一個(gè)動(dòng)態(tài)特征:有些變量只要我們進(jìn)入其作用域,就可以訪問。 有的,我們必須等到執(zhí)行到它們的聲明。

下表總結(jié)了不同聲明的方式如何處理上述兩個(gè)方面。

“Duplicates”描述是否可以在同一作用域內(nèi)聲明兩次。

“Global prop.”表示一個(gè)在 script 中的聲明,當(dāng)全局作用域中被執(zhí)行時(shí),是否會(huì)向全局對(duì)象添加屬性。

TDZ 表示暫時(shí)性死區(qū)(稍后解釋)。 函數(shù)聲明在嚴(yán)格模式下是塊作用域的(例如在模塊內(nèi)部),但在非嚴(yán)格模式下是函數(shù)作用域。

2. const 和 let :暫時(shí)性死區(qū)

對(duì)于JavaScript,TC39 需要決定如果在聲明之前訪問其直接作用域中的常量會(huì)發(fā)生什么:

{
  console.log(x); // 這里會(huì)發(fā)生什么?
  const x;
}

主要有兩種種情況:

打印 undefined

報(bào)錯(cuò)

第一種不會(huì)出現(xiàn),因?yàn)?x 是一個(gè)常量,如果打印 undefined,在聲明前和聲明后它將擁有不同的值,x 就不是常量了。

let 和 const 都會(huì)出現(xiàn)第二種情況,就是會(huì)報(bào)錯(cuò)。進(jìn)入變量作用域與執(zhí)行聲明之間的這段時(shí)間被稱為該變量的 臨時(shí)死區(qū)(TDZ)

在臨時(shí)死區(qū)中,變量被認(rèn)為是未初始化的(就像它有一個(gè)特殊的值一樣)。

如果訪問未初始化的變量,將得到ReferenceError 錯(cuò)誤。

一旦執(zhí)行到變量聲明,該變量將被設(shè)置為初始化器的值(通過賦值符號(hào)指定),如果沒有初始化,則為undefined

以下代碼說明了臨時(shí)死區(qū):

if (true) { // 進(jìn)入 `tmp` 的作用域,TDZ 開始
  // `tmp` 未被初始化:
  assert.throws(() => (tmp = "abc"), ReferenceError);
  assert.throws(() => console.log(tmp), ReferenceError);

  let tmp;  // TDZ 結(jié)束
  assert.equal(tmp, undefined);
}

下一個(gè)例子表明臨時(shí)死區(qū)只是 暫時(shí)的 (與時(shí)間有關(guān)):

if (true) { // 進(jìn)入 `myVar` 作用域,TDZ 開始
  const func = () => {
    console.log(myVar); // 稍后執(zhí)行
  };

  // 我們?cè)?TDZ 中:
  // 訪問 `myVar` 造成 `ReferenceError`

  let myVar = 3; // TDZ 結(jié)束
  func(); // OK,在 TDZ 外調(diào)用
}

即使 func() 位于myVar聲明之前使用 myVar 變量,但我們也可以調(diào)用func(),前提是必須等到myVar的臨時(shí)死區(qū)結(jié)束。

函數(shù)聲明與提前激活

函數(shù)聲明總是在進(jìn)入它的作用域時(shí)執(zhí)行,不管它位于作用域的什么位置。這使得能夠在函數(shù)foo()聲明之前調(diào)用它:

assert.equal(foo(), 123); // ok,相等
function foo() { return 123; }

提前激活 foo()意味著樓上的代碼等價(jià)于

function foo() { return 123; }
assert.equal(foo(), 123);

如果用 constlet 聲明一個(gè)函數(shù),它就不會(huì)被提前激活:在下面的例子中,你只能在 bar() 聲明后調(diào)用它。

assert.throws(
  () => bar(), // 聲明前
  ReferenceError);

const bar = () => { return 123; };

assert.equal(bar(), 123); // 聲明后
在沒有提前激活的情況下提前調(diào)用

即使函數(shù)g()沒有提前激活,也可以被前面的函數(shù) f()(在同一作用域內(nèi))調(diào)用 - 只要遵守以下規(guī)則:f() 必須在聲明 g() 之后調(diào)用

const f = () => g();
const g = () => 123;

// g() 聲明后調(diào)用 f():
assert.equal(f(), 123);

模塊中的函數(shù)通常在模塊執(zhí)行完后調(diào)用。 因此,在模塊中,很少需要擔(dān)心函數(shù)的順序。

最后,注意提前激活是怎樣自動(dòng)執(zhí)行以維持上述規(guī)則的:當(dāng)進(jìn)入一個(gè)作用域時(shí),在任何函數(shù)被調(diào)用前,所有的函數(shù)聲明都會(huì)被先執(zhí)行。

提前激活的一個(gè)陷阱

如果依賴于提前激活機(jī)制,在函數(shù)聲明之前調(diào)用函數(shù),那么需要注意的是它不會(huì)訪問未提前激活的變量。如下:

funcDecl();

const MY_STR = "abc";
function funcDecl() {
   console.log(MY_STR)
}

上述會(huì)報(bào)錯(cuò):

如果你在 MY_STR 聲明之后調(diào)用 funcDecl() 就不會(huì)有問題。

提前激活的利弊

我們已經(jīng)看到提前激活有一個(gè)陷阱,你可以在不使用它的情況下獲得大部分好處。因此,最好避免提前激活。但我對(duì)此說法并非十分認(rèn)同,如前所述,我經(jīng)常使用函數(shù)聲明,因?yàn)槲蚁矚g它們的語法。

類聲明不會(huì)提前激活

類聲明不會(huì)提前激活:

assert.throws(
  () => new MyClass(),
  ReferenceError);

class MyClass {}

assert.equal(new MyClass() instanceof MyClass, true);

這是為什么? 考慮以下類聲明:

class MyClass extends Object {}

extends是可選的,它的操作數(shù)是一個(gè)表達(dá)式。 因此,您可以這樣做:

const identity = x => x;
class MyClass extends identity(Object) {}

計(jì)算這樣的表達(dá)式必須在它被引用的地方完成,其它行為都會(huì)使人困惑。這解釋了為什么類聲明不提前激活。

var :變量提升(部分提前激活)

var是在constlet之前聲明變量的一種較老的方法??紤]下面的var聲明。

var x = 123;

這個(gè)聲明包含兩個(gè)部分:

聲明var x:與大多數(shù)其他聲明一樣,var聲明變量的作用域是最內(nèi)層的包圍函數(shù),而不是最內(nèi)層的包圍塊。這樣的變量在其作用域的開始時(shí)就已處于活動(dòng)狀態(tài),并使用undefined初始化。

賦值 x = 123 :賦值總是在適當(dāng)位置執(zhí)行。

以下代碼演示了 var

function f() {
  // 部分提前激活:
  assert.equal(x, undefined);
  if (true) {
    var x = 123;
    // 賦值已經(jīng)執(zhí)行
    assert.equal(x, 123);
  }
  // 作用域?yàn)楹瘮?shù)作用域,非塊級(jí)作用域。
  assert.equal(x, 123);
}
交流

干貨系列文章匯總?cè)缦?,覺得不錯(cuò)點(diǎn)個(gè)Star,歡迎 加群 互相學(xué)習(xí)。

https://github.com/qq44924588...

我是小智,公眾號(hào)「大遷世界」作者,對(duì)前端技術(shù)保持學(xué)習(xí)愛好者。我會(huì)經(jīng)常分享自己所學(xué)所看的干貨,在進(jìn)階的路上,共勉!

關(guān)注公眾號(hào),后臺(tái)回復(fù)福利,即可看到福利,你懂的。

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

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

相關(guān)文章

  • 揭秘變量提升

    摘要:想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳博客一年百來篇優(yōu)質(zhì)文章等著你引用規(guī)范作者一條最近的推特變量提升是一個(gè)陳舊且令人困惑的術(shù)語。變量提升部分提前激活是在和之前聲明變量的一種較老的方法。 為了保證可讀性,本文采用意譯而非直譯。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 引用 ES6 規(guī)范作者 Allen Wirfs-Brock一條最近的推特: 變量提升是一個(gè)陳舊且令人困惑的...

    Harpsichord1207 評(píng)論0 收藏0
  • 揭秘】云計(jì)算技術(shù)的現(xiàn)狀及特點(diǎn)

    摘要:云計(jì)算有哪些技術(shù)特點(diǎn)很多技術(shù)宅的專家們?cè)?jīng)總結(jié)過云計(jì)算技術(shù)的一些特點(diǎn),下面我們就來概述一下。目前,云計(jì)算技術(shù)在安全問題上已經(jīng)有了長足的進(jìn)步,通過對(duì)數(shù)據(jù)傳輸數(shù)據(jù)存儲(chǔ)數(shù)據(jù)審計(jì)三個(gè)環(huán)節(jié)采取相應(yīng)的安全措施,從而保障整個(gè)云平臺(tái)的安全?! ≡朴?jì)算當(dāng)前處于何種現(xiàn)狀?  我們?cè)谡勅魏我环N新技術(shù)的時(shí)候,用戶往往更關(guān)注技術(shù)所在領(lǐng)域的應(yīng)用程度等問題,對(duì)于云計(jì)算來說,近些年在科研領(lǐng)域的應(yīng)用已經(jīng)取得了突飛猛進(jìn)的進(jìn)展,...

    2i18ns 評(píng)論0 收藏0
  • QuarkChain技術(shù)揭秘 第一話:分片遇上區(qū)塊鏈

    摘要:區(qū)塊鏈水平擴(kuò)容的基本思想是將單根區(qū)塊鏈的狀態(tài)劃分為多條區(qū)塊鏈狀態(tài)。通過增加網(wǎng)絡(luò)中片的數(shù)量,整個(gè)區(qū)塊鏈網(wǎng)絡(luò)的吞吐量將會(huì)線性增加。的宗旨是通過以分片為代表的水平擴(kuò)容技術(shù),建立一個(gè)人人可用的區(qū)塊鏈底層公鏈。 目前,公鏈極低的交易處理能力(TPS)為人們便捷的使用區(qū)塊鏈帶來很大的麻煩。例如:比特幣網(wǎng)絡(luò)只支持6到7個(gè)TPS,而以太坊目前只能處理大約15 TPS,而中心化支付系統(tǒng)的代表:支付寶,在...

    Coly 評(píng)論0 收藏0
  • php數(shù)組原理遍歷原理揭秘

    摘要:數(shù)組原理遍歷原理揭秘?cái)?shù)組原理遍歷原理揭秘可見,數(shù)組其實(shí)已經(jīng)改變了,但是遍歷出來的并沒有增加的哪一項(xiàng)。此時(shí),我們也可以輸出一下當(dāng)前指針位置數(shù)組原理遍歷原理揭秘?cái)?shù)組原理遍歷原理揭秘?cái)?shù)組指針停留在了位置上。 php中的中的數(shù)組跟js里面數(shù)組是不大一樣的。php中數(shù)組的下標(biāo)可以整數(shù)也可以是字符串,而且數(shù)組中元素的順序不是由下標(biāo)決定的,而是由添加元素的順序。數(shù)組基礎(chǔ) $arr1 = array(...

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

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

0條評(píng)論

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