WEB前端學習分享-JavaScript中對象屬性的搜索
本文從來自牛客網的一道測試題為出發點,分享一下對JavaScript中對象屬性的搜索過程的理解
測試題:以下代碼執行后,a.x?和?b.x?的結果分別是?
function A(x){ this.x = x; } A.prototype.x = 1; function B(x){ this.x = x; } B.prototype = new A(); var a = new A(2), b = new B(3);
這道題主要涉及的知識點就是原型對象及對象屬性的搜索,在分析題目之前先簡單看一下相關知識點,詳見《JavaScript高級程序設計》
知識點1:原型對象
每創建一個函數,解析器都會按照特定的規則為這個函數創建一個prototype 屬性,這個屬性實質上是一個指針,指向原型對象,原型對象會默認獲得一個constructor 屬性,指回與之關聯的構造函數。原型對象中除了constructor 這個自帶屬性外,還可以自定義添加其他的屬性和方法。每次調用這個構造函數創建的新實例內部都會有一個隱含的屬性[[prototype]]指向構造函數的原型對象,該構造函數的所有實例都共享原型對象中的屬性和方法。雖然在腳本語言中沒有標準的方式訪問[[prototype]],但是在Firefox,Safari和Chrome中在每個對象上都支持一個屬性__proto__來訪問對象的原型[[prototype]]
知識點2:對象屬性的訪問搜索過程
在通過對象訪問屬性時,會按照這個屬性的名稱開始搜索,它會遵循以下的查找順序:
搜索開始于實例對象本身,如果在這個實例上發現了給定的名稱,則返回該名稱對應的值,不再繼續搜索
如果沒有找到這個屬性,則搜索會沿著指針進入原型對象,如果在原型對象中找到了這個屬性,再返回對應的值,不再繼續搜索。
如果還沒有找到,就去原型對象的原型中去找.....正常的原型鏈都會終止于Object的原型對象,Object的原型對象的原型是null。如果在Object對象的原型中都沒有找到,就到頭了,直接返回undefined.
題目分析
針對以上題目,我自己畫了個草圖供參考,如有錯誤歡迎指正!
function A(x){ this.x = x; } A.prototype.x = 1; //在構造函數A的原型對象上添加變量x,并賦值為1 function B(x){ this.x = x; } //創建構造函數A的一個實例對象,并讓構造函數B的prototype屬性指向這個new A() B.prototype = new A(); //變量a指向new A(2),變量b指向new B(3) var a = new A(2), b = new B(3); delete b.x; //刪除b指向的實例對象new B(3)中的屬性x
查找a.x的過程:
a變量指向new A(2)對象,開始在此對象中查找屬性x,找到x,直接返回值2,搜索停止。
查找b.x的過程:
b變量指向new B(3)對象,在該對象中確實曾經存在過屬性x(值為3),但是在delete b.x;執行完之后存在于實例對象上的屬性x就被delete操作符完全刪除掉了,此時在實例中查找屬性x并不存在,會繼續沿指針進入構造函數B指向的原型對象new A()中,此對象中的x因為沒有傳入實參,賦值為undefined,因此在b.x最后在原型對象中找到了變量x,并將值undefined返回,搜索停止。
console.log(a.x); // 2 console.log(b.x); // undefined
拓展一下
console.log(a.__proto__.x); //1 console.log(b.__proto__.__proto__.x); //1
解答此題的關鍵還是理解構造函數,原型對象,實例對象這3個完全不同的對象
構造函數通過prototype屬性鏈接到原型對象
實例通過[[prototype]]鏈接到原型對象
以上是本人的理解,如有問題,歡迎指正~
JavaScript web前端
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。