深入淺出 Scope Chain 與 Closure
栏目: JavaScript · 发布时间: 5年前
内容简介:Closure 是 ECMAScript 的一大特色,但由於對其不了解,因此很多人不敢使用 Closure;或者雖然會使用 Closure,但仍然對其原理一知半解。本文以 Runtime 角度深入探討 Closure 底層機制 Scope Chain,讓我們徹底了解 Closure 的黑魔法。ECMAScript 5
Closure 是 ECMAScript 的一大特色,但由於對其不了解,因此很多人不敢使用 Closure;或者雖然會使用 Closure,但仍然對其原理一知半解。
本文以 Runtime 角度深入探討 Closure 底層機制 Scope Chain,讓我們徹底了解 Closure 的黑魔法。
Version
ECMAScript 5
ECMAScript 2015
Definition
Closure
當 function 的執行 scope 已經離開 function 所定義的 scope 時,該 function 依然能夠抓到原 scope 的 variable 繼續執行
ECMAScript 5
const makeCounter = function(initial) { return function(step) { return initial += step; } }; const counter = makeCounter(2); console.log(counter(1)); // 3 console.log(counter(2)); // 5 console.log(counter(3)); // 8
ECMAScript 2015
const makeCounter = initial => step => initial += step; const counter = makeCounter(2); console.log(counter(1)); // 3 console.log(counter(2)); // 5 console.log(counter(3)); // 8
這是最簡單的 Closure,ES5 與 ES6 的寫法有一點點差異。
initial
是定義在 makeCounter()
scope 內,然後 return Anonymous function 給 counter
。
當 counter()
執行時,還能抓到 initial
parameter,這就是 Closure 。
Stack 疑雲
我們知道 function 與 method 的 parameter 與 local variable,在執行時期都是存放在 Stack。
執行 makeCounter()
時, initial
parameter 是存放在 Stack,當 makeCounter()
回傳 function 給 counter
後,Stack 會釋放,因此 initial
parameter 也會被釋放,為什麼再次執行 counter()
時,還會抓到 initial
parameter 呢 ?
Scope Chain
在 ECMAScript 中,所有的 variable 都是定義在 scope
object 內,由 key / value 構成,也因為是 object, scope
是在 Heap 內。
const makeCounter = function(initial) { return function(step) { return initial += step; } };
在 code 執行前,ECMAScript 會將所有 variable 存在 global scope object 內。
因此我們有 key 為 makeCounter
,而 value 指向 function 的定義 object。
比較特別的是:每個 function object 有 hidden property [[scope]]
指向定義該 function 的 scope object。
makeCounter(2);
當執行 makeCounter(2)
時,會有自己新的 function scope,因此會建立新的 scope object。
新的 scope object 一樣是由 key / value 構成,除了有 function 該有的 this
、 arguments
外,還有 initial
parameter。
雖然我們是直接 return anonymous function,仍然可以想成有一個 key 為 f
,而 value 指向 function 的定義 object,他也有 [[scope]]
指向 makeCounter()
的 scope object。
比較特別的是:新的 function scope object 有一個 property : outer
指向定義 makeCounter()
的 global scope object,這個 reference 正是由 [[scope]]
複製而來。
const counter = makeCounter(2);
在 global scope object 的 key 新增 counter
,其 value 指向所 return 的 anonymous function。
counter(1);
當執行 counter(1)
時,又有新的 scope object 建立,一樣有 this
與 arguments
,也有 step
parameter 為 1
。
且 outer
property 亦由 [[scope]]
複製而來,因此可以指向 makeCounter()
的 scope object。
當要執行 initial += step
時,在 counter()
的 scope object 並沒有 key 為 initial
的 property,怎麼辦呢 ?
此時 ECMAScript 會透過 outer
property 往上找,在 makeCounter()
scope object 找到 initial
。
由於 scope object 會透過 outer
與 [[scope]]
一層一層往上找,因此稱為 Scope Chain ,這是 Closure 之所以能正常執行的原因。
Conclusion
- Scope object 因為是放在 Heap,而不是放在 Stack,因此不會隨著 function 執行完而釋放
- 只要 scope object
有
被其他 scope object 的outer
property 所參考,則 ECMAScript runtime 的 Garbage Collection 就不會釋放該 scope object,因此 Closure 可以正常執行
以上所述就是小编给大家介绍的《深入淺出 Scope Chain 與 Closure》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 【1】JavaScript 基础深入——数据类型深入理解与总结
- 深入理解 Java 函数式编程,第 5 部分: 深入解析 Monad
- 深入理解 HTTPS
- 深入理解 HTTPS
- 深入浅出Disruptor
- 深入了解 JSONP
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
爆款:如何打造超级IP
【美】安妮塔•埃尔伯斯 / 杨雨 / 中信出版社 / 2016-1-10 / 49
哈佛商学院IP运营与产品管理方法论第一书,翻转长尾理论的重要著作! 电影大片、当红炸子鸡、百万畅销书背后的运营逻辑是什么? 《五十度灰》、Lady Gaga、维多利亚的秘密有何共同秘密? 漫威如何将蜘蛛侠、X战警、绿巨人打造成金矿? 皇马如何打造体育IP,一跃成为全球收 入最高的足球俱乐部? 爆款策略如何运用于电影、电视、音乐、出版、体育与商业各领域? ----......一起来看看 《爆款:如何打造超级IP》 这本书的介绍吧!
JS 压缩/解压工具
在线压缩/解压 JS 代码
Base64 编码/解码
Base64 编码/解码