摘要:同時構造函數內部的被指定為。這時的作用域鏈是由的活動對象和全局對象組成的。在被調用時,它自身的活動對象被創建,然后添加到了中存儲著的作用域鏈的最前方。當函數執行完畢時活動對象會被從該作用域鏈上刪除。參考自運算符作用域原理譯函數的作用域鏈
new的運行機制
當代碼new Animal("cat")執行時:
var obj=Object.create(Animal.prototype);
傳入cat參數,構造函數Animal執行。同時構造函數內部的this被指定為obj。
如果構造函數返回了一個“對象”,那么這個對象就是new出來的結果。如果構造函數沒有返回對象(即返回一個非對象值,例如數值,或者無返回值),那么new出來的結果為obj對象。一般情況下構造函數不返回值,除非你想要覆蓋正常創建的對象(即obj)。
例如:
function A(name){ this.name=name; return 3; } var new1=new A("aa"); new1;//A {name: "aa"} function B(name){ this.name=name; return {}; } var new2=new B("aa"); new2;//new2為一個空對象。作用域鏈
JS權威指南中有一句很精辟的描述: “JavaScript中的函數運行在它們被定義的作用域里,而不是它們被執行的作用域里。”簡單來說,就是函數被調用時,它是運行在當時定義該函數時的環境中的。
定義函數當定義函數a的時候,js解釋器會將函數a的作用域鏈(scope chain)設置為定義a時所在的“環境”,并為a添加scope屬性,a.scope=a的作用域鏈。如果a定義在全局環境,那么scope chain中只有window對象。
調用函數當函數被調用時,會創建一個活動對象(call object)(也就是一個對象), 然后把所有函數a的局部變量和函數定義添加為該活動對象的屬性, 并將該活動對象添加到a的作用域鏈的最頂端,此時a的作用域鏈包含2個對象:a的活動對象和window對象。
案例解析為什么調用func1(10)和func2(10)時,引用到了兩個不同的i?
function outerFn(i, j) { var x = i + j; return function innerFn(x) { return i + x; } } var func1 = outerFn(5, 6); var func2 = outerFn(10, 20); alert(func1(10)); //返回15 alert(func2(10)); //返回20
調用outerFn (5, 6)的時候定義了一個新的函數對象innerFn,然后該函數對象成為了outerFn函數的活動對象的一個屬性。這時innerFn的作用域鏈是由outerFn的活動對象和全局對象組成的.。這個作用域鏈存儲在了innerFn函數的內部屬性[[scope]]中,然后返回了該函數,變量func1就指向了這個innerFn函數。
在func1被調用時,它自身的活動對象被創建,然后添加到了[[scope]]中存儲著的作用域鏈的最前方。這時的作用域鏈才是func1函數執行時用到的作用域鏈。從這個作用域鏈中,可以看到變量‘i’的值實際上就是在執行outerFn(5,6)時產生的活動對象的屬性i的值。下圖顯示了整個流程。
下圖是func2執行時的情況。因為在定義func1和func2時,函數outerFn中產生過兩個不同的活動對象,所以才導致調用func1(10)和func2(10)時,引用到了兩個不同的i。
一個活動對象在函數執行的時候創建,同時被添加到該函數的作用域鏈的最前端。當函數執行完畢時,活動對象會被從該作用域鏈上刪除。但是該活動對象是否會被垃圾回收器銷毀,還要看其他地方是否還有使用到該活動對象。
參考自:
new運算符
Javascript作用域原理
[譯]JavaScript:函數的作用域鏈
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89618.html
摘要:作用域鏈的用途,是保證對執行環境有權訪問的變量和函數的有序訪問。全局執行環境始終是作用域鏈的最后一個對象。延長作用域鏈雖然執行環境的類型只有兩種。 最近在忙于寫一個react+node的全棧博客demo,沒有時間更新文章。但是還是覺得這樣一忙起來不更新是不應該的。正好在空閑上下班地鐵上都會再去細讀js原生知識。所以打算整理、總結、系統性的分享給大家。 基本類型和引用類型 在ECMASc...
摘要:自由變量指的是不在函數內部聲明的變量。作用域鏈就是在所有內部環境中查找變量的鏈式表。閉包的形式閉包的過程寫的不是很嚴謹。 要弄懂這個問題首先要搞清楚一個概念, 執行上下文。 執行上下文 執行上下文是什么? 可以簡單理解執行上下文是js代碼執行的環境,當js執行一段可執行代碼時,會創建對應的執行上下文。他的組成如下: executionContextObj = { this: 對...
摘要:前言這段時間一直在消化作用域鏈和閉包的相關知識。而作用域鏈則是這套規則這套規則的具體運行。是變量對象的縮寫那這樣放有什么好處呢我們知道作用域鏈保證了當前執行環境對符合訪問權限的變量和函數的有序訪問。 前言:這段時間一直在消化作用域鏈和閉包的相關知識。之前看《JS高程》和一些技術博客,對于這些概念的論述多多少少不太清楚或者不太完整,包括一些大神的技術文章。這也給我的學習上造成了一些困惑,...
摘要:該對象包含了函數的所有局部變量命名參數參數集合以及,然后此對象會被推入作用域鏈的前端。如果整個作用域鏈上都無法找到,則返回。此時的作用域鏈包含了兩個對象的活動對象和對象。 前端學習:教程&開發模塊化/規范化/工程化/優化&工具/調試&值得關注的博客/Git&面試-前端資源匯總 歡迎提issues斧正:閉包 JavaScript-閉包 閉包(closure)是一個讓人又愛又恨的somet...
摘要:在此例中,在匿名函數被返回后,它的作用域鏈初始化為包含函數的活動對象和全局變量對象。函數在執行完畢后,其活動對象也不會被銷毀,因為匿名函數的作用域鏈仍然在引用這個活動對象,結果就是只是的執行環境的作用域鏈會被銷毀,其活動對象會留在內存中。 寫在前面 注:這個系列是本人對js知識的一些梳理,其中不少內容來自書籍:Javascript高級程序設計第三版和JavaScript權威指南第六版,...
閱讀 2722·2021-11-11 17:21
閱讀 613·2021-09-23 11:22
閱讀 3578·2019-08-30 15:55
閱讀 1641·2019-08-29 17:15
閱讀 573·2019-08-29 16:38
閱讀 904·2019-08-26 11:54
閱讀 2504·2019-08-26 11:53
閱讀 2750·2019-08-26 10:31