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

資訊專欄INFORMATION COLUMN

Javascript閉包:從理論到實(shí)現(xiàn),[[Scopes]]的每一根毛都看得清清楚楚

Chiclaim / 558人閱讀

摘要:昨天我寫到所有函數(shù)都是閉包,有些同學(xué)表示還是接受不能。換句話說,它正是函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合。原因詳見我的上一篇文章從過程式到函數(shù)式。我的相關(guān)文章閉包從過程式到函數(shù)式以上所有代碼按授權(quán)。

昨天我寫到“所有Javascript函數(shù)都是閉包”,有些同學(xué)表示還是接受不能。我好好的一個函數(shù),怎么就成閉包了?那么,讓我們來探究一下,Chrome(V8)到底是怎樣實(shí)現(xiàn)閉包的。

從閉包到[[Scopes]]

現(xiàn)在按下F12,打開console,讓我們隨便找一個實(shí)驗(yàn)對象:

function simpleFunc() { }
// <- undefined

超簡單超正常的函數(shù)吧,我們來驗(yàn)證一下:

simpleFunc
// <- ? simpleFunc() { }

說了超正常的,哪里閉包了?現(xiàn)在試試這個:

console.dir(simpleFunc)
// ? simpleFunc()
//   arguments: null
//   caller: null
//   length: 0
//   name: "simpleFunc"
//   prototype: {constructor: ?}
//   __proto__: ? ()
//   [[FunctionLocation]]: VM000:1
//   [[Scopes]]: Scopes[1]

咦,[[Scopes]]是什么?打開一看:

//   [[Scopes]]: Scopes[1]
//     0: Global?{type: "global", name: "", object: Window}

這就是閉包的實(shí)現(xiàn)。東西都存在這里了。看起來simpleFunc只不過是純潔的函數(shù),但它實(shí)際上是(空的)自身代碼+全局變量環(huán)境。換句話說,它正是“函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合”。

再來個稍微復(fù)雜點(diǎn)的例子:

{
  let localVar = 1;
  function dirtyFunc() { return localVar++ }
}
// <- ? dirtyFunc() { return localVar++ }
console.dir(dirtyFunc)
// ? dirtyFunc()
//   [[Scopes]]: Scopes[2]
//     0: Block
//       localVar: 1
//     1: Global {type: "global", name: "", object: Window}

看,localVar存在這里了吧!大家老說什么“保持運(yùn)行的數(shù)據(jù)狀態(tài)”云云,其實(shí)都在[[Scopes]]里。dirtyFunc看起來是個普通的函數(shù),但[[Scopes]]里卻混了些東西。

所以,如果我們說人話,閉包實(shí)際上就是——

函數(shù)的代碼+[[Scopes]]

超級好理解了吧。

寧愿用this也不用閉包

接下來讓我們對閉包做些更深入的解析,然后就知道為什么大家寧愿用this也不用閉包了。

[[Scopes]]能用代碼訪問/復(fù)制/修改嗎?

不能。想不靠console,找到副作用在哪兒?不行。想深拷貝目前狀態(tài)?不行。想歷史回放?不行。debug?自己慢慢琢磨去吧!

閉包會把所有東西都存下來嗎?
{
  let localVar = 1;
  let unusedVar = 2;
  function dirtyFunc2() { return localVar++ }
}
console.dir(dirtyFunc2)
// ? dirtyFunc()
//   [[Scopes]]: Scopes[2]
//     0: Block
//       localVar: 1
//     1: Global {type: "global", name: "", object: Window}

至少Chrome是不會把所有東西都塞到閉包里的。

那閉包對垃圾回收沒害處?
{
  let localVar = new Uint8Array(1000000000)
  function dirtyFunc3() { return localVar }
  function cleanFunc() { }
}
var dirtyFunc3 = null
console.dir(cleanFunc)
// ? cleanFunc()
//   [[Scopes]]: Scopes[2]
//     0: Block
//       localVar: Uint8Array(1000000000) [0, 0, …]
//     1: Global {type: "global", name: "", object: Window}

dirtyFunc3cleanFunc共享同一個[[Scopes]]項,但這個[[Scopes]]項并不會因?yàn)?b>dirtyFunc3被回收而動態(tài)更新!所以無辜的cleanFunc就只好一直帶著這1GB的垃圾,內(nèi)存泄漏妥妥的。作為強(qiáng)迫癥,這是我討厭閉包最重要的原因。

真的所有Javascript函數(shù)都是閉包嗎?
console.dir(alert)
// ? dirtyFunc()
//   [[Scopes]]: Scopes[0]
//     No properties

抱歉,我可能是不太嚴(yán)謹(jǐn)。很明顯,瀏覽器自帶的原生API函數(shù)都是在【里世界】聲明的,所以沒有詞法環(huán)境,自然[[Scopes]]是空的。它們不是閉包。

最佳實(shí)踐

寧愿用this也不用閉包。原因詳見我的上一篇文章(從過程式到函數(shù)式)。

我的相關(guān)文章

Javascript閉包:從過程式到函數(shù)式

以上所有代碼按Mozilla Public License, v. 2.0授權(quán)。
以上所有文字內(nèi)容按CC BY-NC-ND 4.0授權(quán)。

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

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

相關(guān)文章

  • Javascript閉包過程式函數(shù)式

    摘要:想方設(shè)法糅合過程式與函數(shù)式兩種風(fēng)格,忽略了閉包的基本假設(shè),于是造出天坑。分散在各個閉包中的狀態(tài)會成為的溫床。當(dāng)然,嚴(yán)格來說箭頭函數(shù)也是一種閉包,因?yàn)樗呛瘮?shù)和詞法的組合。 編程語言的究極問題:過程式還是函數(shù)式? 閉包是函數(shù)式編程最先引進(jìn)的,基本假設(shè)就是所有量都是常量。Javascript想方設(shè)法糅合過程式與函數(shù)式兩種風(fēng)格,忽略了閉包的基本假設(shè),于是造出天坑。 是什么 閉包的定義是函數(shù)和...

    leone 評論0 收藏0
  • JavaScript基礎(chǔ)系列---閉包及其應(yīng)用

    摘要:所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。所以本文中將以維基百科中的定義為準(zhǔn)即在計算機(jī)科學(xué)中,閉包,又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。 閉包(closure)是JavaScript中一個神秘的概念,許多人都對它難以理解,我也一直處于似懂非懂的狀態(tài),前幾天深入了解了一下執(zhí)行環(huán)境以及作用域鏈,可戳查看詳情,而閉包與作用域及作用域鏈的關(guān)系密不可分,所...

    leoperfect 評論0 收藏0
  • 前端學(xué)習(xí)筆記之閉包——看了一張圖終于明白啥是閉包

    摘要:在一個閉包環(huán)境內(nèi)修改變量值,不會影響另一個閉包中的變量。直到看到函數(shù)閉包閉包這篇文章的代碼一部分,終于明白其中的邏輯了。 閉包 閉包定義:指擁有多個變量和綁定了這些變量的環(huán)境的表達(dá)式(通常是一個函數(shù)),因而這些變量也是該表達(dá)式的一部分。函數(shù)內(nèi)部可以直接讀取全局變量。函數(shù)內(nèi)部變量無法在函數(shù)外部訪問。函數(shù)內(nèi)部聲明要用var或者let聲明,不然會變成全局變量鏈?zhǔn)阶饔糜颍鹤訉ο髸患壖壪蛏蠈ふ?..

    andycall 評論0 收藏0
  • PyTips 0x04 - Python 閉包與作用域

    摘要:項目地址閉包在計算機(jī)科學(xué)中,閉包英語,又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。 項目地址:https://git.io/pytips 閉包(Closure) 在計算機(jī)科學(xué)中,閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數(shù)閉包(function closures),是...

    leejan97 評論0 收藏0
  • Lexical environments: ECMAScript implementation

    摘要:全局環(huán)境是作用域鏈的終點(diǎn)。環(huán)境記錄類型定義了兩種環(huán)境記錄類型聲明式環(huán)境記錄和對象環(huán)境記錄聲明式環(huán)境記錄聲明式環(huán)境記錄是用來處理函數(shù)作用域中出現(xiàn)的變量,函數(shù),形參等。變量環(huán)境變量環(huán)境就是存儲上下文中的變量和函數(shù)的。解析的過程如下 原文 ECMA-262-5 in detail. Chapter 3.2. Lexical environments: ECMAScript implement...

    roadtogeek 評論0 收藏0

發(fā)表評論

0條評論

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