[英].isPrototypeOf() and .hasOwnProperty() method confusion
假設我有這個代碼:
// Male will inherit ALL of the Human properties function Human(x, y) { // Following properties will be inherited this.name = x; this.age = y; this.test = "Test 1"; } // Following properties will ALSO be inherited Human.prototype.citizen = "USA"; Human.prototype.employer = "Google"; Human.prototype.test = "Test 2"; function Male(x, y) { // Following properties will be the own properties of Male instances this.name = x; this.age = y; this.gender = "Male"; } // Inheritance - Connecting Male object with Human object Male.prototype = new Human(); // no arguments are passed Male.prototype.constructor = Male; // correcting constructor property var albert = new Male("Albert", 25);
然后,我想對代碼進行一些測試
Human.isPrototypeOf(albert); // I expect it to return TRUE
但它返回FALSE,為什么呢?
並且,對於以下測試
Human.hasOwnProperty("age"); // /i expect it to return TRUE
但它返回FALSE,為什么呢?
謝謝,
編輯我的問題與其他問題略有不同,因為它也談論原型鏈。
Human
功能不在 albert
的原型鏈中。 Human.prototype
引用的對象是:
Human.prototype.isPrototypeOf(albert); // true
Human.hasOwnProperty( “時代”); //我希望它返回TRUE
Human
函數沒有age
屬性。 用new
創建的實例:
new Human().hasOwnProperty("age"); // true
旁注:您設置繼承鏈的方式很常見,並在很多示例中顯示,但在兩個方面不正確:
您不想使用new Human
來創建Male.prototype
。
你想叫Human
從Male
:
所以:
function Male(x, y) {
// Give Human its chance to initialize the object (#2)
Human.call(this, x, y);
// ...
}
// Don't use new Human to create the prototype (#1)
Male.prototype = Object.create(Human.prototype);
Male.prototype.constructor = Male;
你不使用new Human
為Male
創建原型的原因很簡單: Human
期望參數,但你沒有任何東西可以給它。
這是更新的ES5及該代碼的早期版本:
function Human(name, age) { // Argument names should be meaningful this.name = name; this.age = age; this.test = "Test 1"; } Human.prototype.citizen = "USA"; Human.prototype.employer = "Google"; Human.prototype.test = "Test 2"; function Male(name, age) { Human.call(this, name, age); this.gender = "Male"; } Male.prototype = Object.create(Human.prototype); Male.prototype.constructor = Male; var albert = new Male("Albert", 25); console.log(Human.prototype.isPrototypeOf(albert)); // true console.log(new Human().hasOwnProperty("age")); // true
或者當然,使用ES2015 +(如果您的目標尚不支持,請進行轉換):
// THIS SNIPPET REQUIRES A BROWSER WITH ES2015+ SUPPORT class Human { constructor(name, age) { this.name = name; this.age = age; this.test = "Test 1"; } } Human.prototype.citizen = "USA"; Human.prototype.employer = "Google"; Human.prototype.test = "Test 2"; class Male extends Human { constructor(name, age) { super(name, age); this.gender = "Male"; } } let albert = new Male("Albert", 25); console.log(Human.prototype.isPrototypeOf(albert)); // true console.log(new Human().hasOwnProperty("age")); // true
你已經說過你正在試圖看看鏈是如何運作的。 這是創建albert
后我們在內存中的圖表(為簡單起見,刪除了一些細節):
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | \ +−−−−−−−−−−−−−−−−+ | Human−−−−−>| function | | +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−+ | | prototype |−−−−−−−−−−−−−−−−−−−−−−−−−−−>| object | | | name: "Human" | / +−−−−−−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−+ | | constructor |−+ | | citizen: "USA" | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | employer: "Google" | | | | | test: "Test 2" | \ +−−−−−−−−−−−−−−−−+ | | +−−−−−−−−−−−−−−−−−−−−+ Male−−−−−−>| function | | | +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ | | | prototype |−−−>| object | | | | name: "Male" | / +−−−−−−−−−−−−−−−−−+ | | +−−−−−−−−−−−−−−−−+ | | constructor |−+ | | | [[Prototype]] |−−−+ +−−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−−+ albert−−−−>| object | | +−−−−−−−−−−−−−−−−+ | | name: "Albert" | | | age: 25 | | | gender: "Male" | | | [[Prototype]] |−−+ +−−−−−−−−−−−−−−−−+
[[Prototype]]
是規范用於包含對其原型對象的引用的對象的“內部槽”的名稱。 相比之下, prototype
,函數上的屬性(例如, Human.prototype
),只是函數的一個普通屬性,它指向new
將用作它創建的新對象的[[Prototype]]
的對象,如果你使用它功能與new
。
該圖表上的一些注釋:
[[Prototype]]
內部插槽,指向Function.prototype
指向的對象(為簡單起見,上面省略)。 Human
,這個函數,有一個name
屬性: "Human"
Male
,功能,有一個name
屬性: "Male"
albert
指的是一個name
屬性: "Albert"
albert
的[[Prototype]]
是Male.prototype
; Male.prototype
的[[Prototype]]
是Human.prototype
(和Human.prototype
的[[Prototype]]
,未顯示,是`Object.prototype)。 你在評論中說過:
我只是無法理解為什么繼承語句后我們可以做
Male.prototype.isPrototypeOf(albert)
返回true
而不是Human.isPrototypeOf(albert)
(它返回false
)因為Male.prototype
是Human
一個實例
因為Human
,這個功能,在albert
的原型鏈中是無處可去的。 讓我們看看albert
的原型鏈:
albert
的[[Prototype]]
是Male.prototype
Male.prototype
的[[Prototype]]
是Human.prototype
Human.prototype
的[[Prototype]]
是Object.prototype
Object.prototype
的[[Prototype]]
為null
如圖:
+−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−+ | albert | | Male.prototype | | Human.prototype | | Object.prototype | +−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−+ | [[Prototype]] |−−−>| [[Prototype]] |−−−>| [[Prototype]] |−−−>| [[Prototype]]: null | +−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−+
因此, Human
,這個功能,在這個鏈條中無處可去。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.