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