摘要:如果存在于原型鏈上層,賦值語句的行為就會有些不同。中包含的屬性會屏蔽原型鏈上層的所有屬性,因為總是會選擇原型鏈中最底層的屬性。如果不直接存在于中而是存在于原型鏈上層時會出現的三種情況。類構造函數原型函數,兩個函數通過屬性和屬性相關聯。
1 [[Prototype]]
對于默認的 [[Get]] 操作來說,如果無法在對象本身找到需要的屬性,就會繼續訪問對象的 [[Prototype]] 鏈
所有普通的 [[Prototype]] 鏈最終都會指向內置的 Object.prototype。由于所有的“普通”(內置,不是特定主機的擴展)對象都“源于”(或者說把 [[Prototype]] 鏈的頂端設置為)這個 Object.prototype 對象,如:toString,valueOf,hasOwnProperty,isPrototypeOf
var anotherObject = { a:2}; // 創建一個關聯到 anotherObject 的對象 var myObject = Object.create( anotherObject ); // myObject = { __proto__: { a:2, __proto__: Object}}; myObject.a; // 2
屬性屏蔽
給一個對象設置屬性并不僅僅是添加一個新屬性或者修改已有的屬性值,如myObject.foo = "bar";
如果 myObject 對象中包含名為 foo 的普通數據訪問屬性,這條賦值語句只會修改已有的屬性值。
如果 foo 存在于原型鏈上層,賦值語句 myObject.foo = "bar" 的行為就會有些不同。
如果屬性名 foo 既出現在 myObject 中也出現在 myObject 的 [[Prototype]] 鏈上層,那么就會發生屏蔽。myObject 中包含的 foo 屬性會屏蔽原型鏈上層的所有 foo 屬性,因為myObject.foo 總是會選擇原型鏈中最底層的 foo 屬性。
如果 foo 不直接存在于 myObject 中而是存在于原型鏈上層時 myObject.foo = "bar" 會出現的三種情況。
如果在[[Prototype]]鏈上層存在名為foo的普通數據訪問屬性(參見第3章)并且沒有被標記為只讀(writable:false),那就會直接在 myObject 中添加一個名為 foo 的新屬性,它是屏蔽屬性。
如果在[[Prototype]]鏈上層存在foo,但是它被標記為只讀(writable:false),那么無法修改已有屬性或者在 myObject 上創建屏蔽屬性。如果運行在嚴格模式下,代碼會拋出一個錯誤。否則,這條賦值語句會被忽略。總之,不會發生屏蔽。
如果在[[Prototype]]鏈上層存在foo并且它是一個setter(參見第3章),那就一定會調用這個 setter。foo 不會被添加到(或者說屏蔽于)myObject,也不會重新定義 foo 這個 setter。
大多數開發者都認為如果向 [[Prototype]] 鏈上層已經存在的屬性([[Put]])賦值,就一定會觸發屏蔽,但是如你所見,三種情況中只有一種(第一種)是這樣的。如果你希望在第二種和第三種情況下也屏蔽 foo,那就不能使用 = 操作符來賦值,而是使用 Object.defineProperty(..)來向 myObject 添加 foo。
2 “類”構造函數+原型函數,兩個函數通過 constructor 屬性和 prototype 屬性相關聯。
類關系
function Foo() {} let foo = new Foo();
1 foo instanceof Foo
instanceof 操作符的左操作數是一個普通的對象,右操作數是一個函數。instanceof 回答的問題是:在 a 的整條 [[Prototype]] 鏈中是否有指向 Foo.prototype 的對象
2 Foo.prototype.isPrototypeOf( foo )
isPrototypeOf(..) 回答的問題是:在 foo 的整條 [[Prototype]] 鏈中是否出現過 Foo.prototype 。我們也可以直接獲取一個對象的 [[Prototype]] 鏈。Object.getPrototypeOf(foo); 如Object.getPrototypeOf( foo ) === Foo.prototype; // true 或者 a.__proto__ === Foo.prototype; // true
?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109944.html
摘要:如果存在于原型鏈上層,賦值語句的行為就會有些不同。中包含的屬性會屏蔽原型鏈上層的所有屬性,因為總是會選擇原型鏈中最底層的屬性。如果不直接存在于中而是存在于原型鏈上層時會出現的三種情況。類構造函數原型函數,兩個函數通過屬性和屬性相關聯。 1 [[Prototype]] 對于默認的 [[Get]] 操作來說,如果無法在對象本身找到需要的屬性,就會繼續訪問對象的 [[Prototype]] ...
摘要:上一篇你不知道的筆記寫在前面這是年第一篇博客,回顧去年年初列的學習清單,發現僅有部分完成了。當然,這并不影響年是向上的一年在新的城市穩定連續堅持健身三個月早睡早起游戲時間大大縮減,學會生活。 上一篇:《你不知道的javascript》筆記_this 寫在前面 這是2019年第一篇博客,回顧去年年初列的學習清單,發現僅有部分完成了。當然,這并不影響2018年是向上的一年:在新的城市穩定、...
摘要:隱式綁定即綁定到最頂層或最近調用對象上顯式綁定即用或手動進行綁定方法實現綁定構造函數不存在其實在中不存在構造函數,我們所說的構造函數其實就是普通的函數,它只是用被構造調用而已。 JS是編譯型語言 編譯發生在代碼執行前幾微秒,簡單來說就是js在執行前要進行編譯,編譯過程發生在代碼執行前幾微妙,甚至更短。 編譯的步驟 詞法分析以var a = 2 為例,詞法分析會將其分成三個有意義的代碼...
摘要:內置對象,在中,它們實際上只是一些內置函數。這些內置函數可以當作構造函數,使用調用,產生新對象。在必要時語言會自動把字符串字面量轉換成一個對象,也就是說你并不需要顯式創建一個對象。屬性操作符要求屬性名滿足標識符的命名規范。 1 如何定義 // 聲明形式,大部分情況下使用聲明形式 let obj ={ a:2, b:3 }; // 構造形式 let obj= = new Obje...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...
閱讀 1505·2021-11-22 09:34
閱讀 3320·2021-09-29 09:35
閱讀 562·2021-09-04 16:40
閱讀 2912·2019-08-30 15:53
閱讀 2582·2019-08-30 15:44
閱讀 2584·2019-08-30 14:10
閱讀 1328·2019-08-29 18:43
閱讀 2205·2019-08-29 13:26