簡體   English   中英

了解Javascript原型繼承

[英]Understanding Javascript prototypical inheritance

恐怕要問這個問題,因為在同一主題上已經有很多這樣的問題。

我試圖了解使用approach-1approach-2缺點/局限性

簡單繼承

 function Person(name, age) { this.name = name || "de-name"; this.age = !!Number(age) ? Number(age) : 0; } Person.prototype.setName = function(name) { this.name = name; return this; } function Student(name) { Person.call(this, name); // Copy instance properties of Person class this.title = "Student"; } // Suggested way Student.prototype = Object.create(Person.prototype); // Possible approach-1 // Student.prototype = Person.prototype; // Possible approach-2 // Student.prototype = new Person(); 

在基於原型的語言中,繼承是通過克隆用作原型而不是具有類的現有對象來執行的。

因此,在每種情況下,我們都應該考慮選擇用作原型的對象以確定行為的方式。

在方法1中,您將Student的原型設置為與Person相同的原型對象。 這意味着對Student.prototype所做的任何更改都會影響Person.prototype ,反之亦然。

在方法2中,您將Student的原型設置為一個新的Person對象,該對象將根據您的初始化代碼將以下屬性設置為{name: 'de-name', age: 0} 然后,您在Student函數中對Person.call()調用將覆蓋name屬性。 由於這是一個全新的對象,因此對Student.prototype任何修改將僅影響新的Student對象,並且此Person實例上作為原型的任何缺少的屬性都將委派給Person.prototype

為了詳細說明最后一點(缺少的屬性在原型鏈中傳遞),下面是一個示例。 假設我們添加一個新的方法greetPerson

Person.prototype.greet = function() { console.log("Hi! " + this.name; ) }

調用new Student().greet()將使JavaScript在原型鏈中進行檢查,直到遇到適當的屬性為止(否則,您將得到未定義的錯誤。)

// Walking up the chain
/* 1 */ new Student()     // doesn't have a greet property
/* 2 */ Student.prototype // => Person {name: 'de-name', age: 0}
// This person instance doesn't have a greet property either
// because we instantiated it before adding the `greet` property
/* 3 */ Person.prototype  // Has a greet property which gets called

Object.create的建議模式中,您執行的操作與Student.prototype = new Person()幾乎相同,只是Object.create允許您執行差異繼承 您甚至可以添加其他屬性作為其第二個參數:

Student.prototype = Object.create(Person.prototype, {
  age: 16,
  study: function() { console.log("But I'm sooo lazy!!!"); } 
});

實際上,方法1和方法2並不完全相同。 在方法2中,您將創建一個Person的新實例,並將該新實例分配給Student的原型。

此外,您應該這樣做:

var Student = Object.create(Person.prototype);

根據MDN

The Object.create() method creates a new object with the specified prototype object and properties.

因此,您無需將其分配給Student原型,而是將其分配給Student本身,然后Student獲得Person作為其原型。

Approach-2表示原型鏈中的另一個對象。 如果(new Student()).someAttr沒有在學生對象( new Student() )中解析,則采用方法2,將檢查人員對象( new Person() )(因為這是Student.prototype ),然后Person.prototype 使用方法1時,沒有人對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM