摘要:這幾天因為對于中的作用域鏈和原型鏈有點混淆,當(dāng)訪問一個不帶有修飾的變量時,我想知道它的搜索順序,因為作用域鏈的鏈結(jié)點也是一個變量對象,那么當(dāng)在這個變量對象中查找變量時會不會沿著它的原型鏈查找呢這樣就有兩種可能先查找作用域鏈前端的變量對象,然
這幾天因為對于JavaScript中的作用域鏈和原型鏈有點混淆,當(dāng)訪問一個不帶有this修飾的變量時,我想知道它的搜索順序,因為作用域鏈的鏈結(jié)點也是一個變量對象,那么當(dāng)在這個變量對象中查找變量時會不會沿著它的原型鏈查找呢?這樣就有兩種可能:
先查找作用域鏈前端的變量對象,然后再查找它的原型,然后再查找作用域鏈中下一個變量對象,然后再查找它的原型;
一直查找作用域鏈中的變量對象,直到window對象,再查找它的原型。
然而在使用with語句做實驗時,發(fā)現(xiàn)了下面的現(xiàn)象,因此本篇文章是我對下面的事實作出的猜測和理解,望指正!
考察下列代碼:
Object.prototype.s=10; (function(){ var s=25; var obj={}; obj.__proto__={}; obj.__proto__.__proto__={s:15}; with(obj){ console.log(s);//輸出15 } }());
上述代碼中,在Object.prototype中定義了一個屬性s=10,在匿名函數(shù)中定義一個變量s=25,其中又有一個對象obj,在obj的二級原型鏈中定義一個屬性s=15,然后,使用with將這個對象obj掛在作用域鏈頂端,輸出s,但是它輸出了15.
對此我做出的猜測是:在搜查變量中實際上是一個二維的過程而不是一維的,它構(gòu)造出的二維鏈?zhǔn)沁@樣子的:
所以上述過程中,先從obj(即作用域鏈頂端的變量對象開始搜查),因為obj本身沒有s,則沿著obj的原型鏈搜查,在二級原型鏈中找到了s=15,從而停止搜查,返回s=15的值,故而輸出15.
按照這個思路,發(fā)現(xiàn)所有對象的原型鏈都最終指向Obje.prototype,所以為了驗證這個猜想,做下述實驗,即刪除s=15這個語句
Object.prototype.s=10; //保留Object.prototype中的s (function(){ var s=25; var obj={}; obj.__proto__={}; obj.__proto__.__proto__={};//刪除了s:15 with(obj){ console.log(s);//輸出10 } }());
上述代碼輸出了10,這就是說,沿著第一個作用域鏈結(jié)點的原型鏈找,最終在Objec.prototype中找到了s,從而停止查找,那么函數(shù)中s=25沒有遍歷到
下面做個實驗,證明確實是二維查找。
使用嵌套的with語句,在作用域鏈頂端掛兩個對象,其中第二個對象是一個函數(shù)對象,而s正是在Function.prototype中,如果上面的猜想可行,那么應(yīng)該能正確輸出s,而事實上確實如此
Function.prototype.s=5;//給Funct.prototype添加s var obj={}; var func=function(){}; (function(){ var s=25; //s=25 with(func){ //嵌套 with(obj){ console.log(s); //輸出5 } } }());
上述輸出的正是5,其過程如下所示:
最后要特別說明的是,函數(shù)對象本身和函數(shù)的上下文不是同一個東西,比如上圖中,我并不知道匿名函數(shù)上下文的__proto__指向哪里,但是我認(rèn)為它不會指向Function.prototype,因為如果Function.prototype在匿名函數(shù)上下文的繼承鏈中,那么下面代碼應(yīng)該能正常輸出:
Function.prototype.s=5;//給Funct.prototype添加s var obj={}; (function(){ with(obj){ console.log(s); //輸出???? } }());
也就是說,因為obj本身沒有s,一直找到Object.prototype中也沒有s,轉(zhuǎn)而從作用域鏈的下一節(jié)點也即匿名函數(shù)上下文尋找,同時匿名函數(shù)中也沒有s,如果Function.prototype在匿名函數(shù)上下文的繼承鏈中,那么應(yīng)該能找到s=5,但是很遺憾,上面輸出的是
Uncaught ReferenceError: s is not defined。
若改成下面這樣則能正常輸出15,因為s本身就在匿名函數(shù)的上下文中
Function.prototype.s=5;//給Funct.prototype添加s var obj={}; (function(s=15){ //參數(shù) with(obj){ console.log(s); //輸出15 } }());
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/86934.html
摘要:如果此對象表示非靜態(tài)上下文中聲明的內(nèi)部類,則形參類型作為第一個參數(shù)包括顯示封閉的實例。參數(shù)字段名返回此類中指定字段的對象拋出如果找不到帶有指定名稱的字段。 一、類的加載 1. 概述 當(dāng)程序要使用某個類時,如果該類還未被加載到內(nèi)存中,則系統(tǒng)會通過加載,連接,初始化三步來實現(xiàn)對這個類進(jìn)行初始化 2. 加載 就是指將class文件讀入內(nèi)存,并為之創(chuàng)建一個Class對象 任何類被使用時系統(tǒng)都...
摘要:的正則表達(dá)式體系是參照建立的。字面量形式構(gòu)造函數(shù)形式以上都是創(chuàng)建了一個內(nèi)容為的正則表達(dá)式,其表示對一個手機號碼的校驗。按照給定的正則表達(dá)式進(jìn)行替換,返回替換后的字符串。 正則表達(dá)式,也稱規(guī)則表達(dá)式,經(jīng)常使用其來完成對字符串的校驗和過濾。由于正則表達(dá)式的靈活性、邏輯性和功能性都非常強大,而且 可以利用很簡單的方式完成對復(fù)雜字符串的控制,所以很多程序語言都支持正則表達(dá)式。在JavaScri...
摘要:驗證驗證階段的主要目的是為了確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機的要求,并且不會危害虛擬機自身的安全。不同的虛擬機對類驗證的實現(xiàn)可能會有所不同,但大致都會完成以下四個階段的驗證文件格式的驗證元數(shù)據(jù)的驗證字節(jié)碼驗證和符號引用驗證。 原文地址 虛擬機把描述類的數(shù)據(jù)從Class文件加載到內(nèi)存,并對數(shù)據(jù)進(jìn)行校驗,轉(zhuǎn)換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,Thisis ...
摘要:廣州三本大三在讀,在廣州找實習(xí)。這篇文章其實主要是記錄一下自己的面試經(jīng)歷,希望大家看完之后能有所了解進(jìn)入中小公司究竟需要什么水平。時間復(fù)雜度盡量低一些使用快排的,將給出的隨機數(shù)做基準(zhǔn)值返回的坐標(biāo)就是了。 前言 只有光頭才能變強 這陣子跑去面試Java實習(xí)生啦~~~我來簡單介紹一下背景吧。 廣州三本大三在讀,在廣州找實習(xí)。大學(xué)開始接觸編程,一個非常平庸的人。 在學(xué)習(xí)編程時,跟我類似的人應(yīng)...
摘要:規(guī)范目的為提高團隊協(xié)作效率便于后臺人員添加功能及前端后期優(yōu)化維護輸出高質(zhì)量的文檔特制訂此文檔。 規(guī)范目的 為提高團隊協(xié)作效率, 便于后臺人員添加功能及前端后期優(yōu)化維護, 輸出高質(zhì)量的文檔, 特制訂此文檔。 文件規(guī)范 文件命名規(guī)則 文件名稱統(tǒng)一用小寫的英文字母、數(shù)字和下劃線的組合,其中不得包含漢字、空格和特殊字符;命名原則的指導(dǎo)思想一是使得你自己和工作組的每一個成員能夠方便的理解每一個...
閱讀 1379·2023-04-25 19:33
閱讀 1242·2021-10-21 09:39
閱讀 3711·2021-09-09 09:32
閱讀 2716·2019-08-30 10:58
閱讀 1722·2019-08-29 16:17
閱讀 933·2019-08-29 15:29
閱讀 2963·2019-08-26 11:55
閱讀 2726·2019-08-26 10:33