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