function Parent () {
this.name = 'kevin';
}
Parent.prototype.getName = function () {
console.log(this.name);
}
function Child () {
}
Child.prototype = new Parent();
var child1 = new Child();
console.log(child1.getName()) // kevin
複製代碼
缺點bash
function Parent () {
this.names = ['kevin', 'daisy'];
}
function Child () {
}
Child.prototype = new Parent();
var child1 = new Child();
child1.names.push('yayu');
console.log(child1.names); // ["kevin", "daisy", "yayu"]
var child2 = new Child();
console.log(child2.names); // ["kevin", "daisy", "yayu"]
複製代碼
function Parent () {
this.names = ['kevin', 'daisy'];
}
function Child () {
Parent.call(this);
}
var child1 = new Child();
child1.names.push('yayu');
console.log(child1.names); // ["kevin", "daisy", "yayu"]
var child2 = new Child();
console.log(child2.names); // ["kevin", "daisy"]
複製代碼
優勢函數
function Parent (name) {
this.name = name;
}
function Child (name) {
Parent.call(this, name);
}
var child1 = new Child('kevin');
console.log(child1.name); //kevin
var child2 = new Child('daisy');
console.log(child2.name); // daisy
複製代碼
缺點ui
function Parent (name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.getName = function () {
console.log(this.name)
}
function Child (name, age) {
Parent.call(this, name);
this.age = age;
}
Child.prototype = new Parent();
var child1 = new Child('kevin', '18');
child1.colors.push('black');
console.log(child1.name); // kevin
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]
var child2 = new Child('daisy', '20');
console.log(child2.name); // daisy
console.log(child2.age); // 20
console.log(child2.colors); // ["red", "blue", "green"]
複製代碼
優勢this
function createObj (o) {
function F () {}
F.prototype = o;
return new F();
}
複製代碼
就是ES5 Object.create的模擬實現,將傳入的對象做爲做爲建立的對象的原型。spa
缺點prototype
包含引用類型的屬性值始終都會共享相應的值,這點跟原型鏈繼承同樣。code
var person = {
name: 'kevin',
friends: ['daisy', 'kelly']
}
var person1 = createObj(person);
var person2 = createObj(person);
person1.name = 'person1';
console.log(person2.name); // kevin
person1.friends.push('taylor');
console.log(person2.friends); // ["daisy", "kelly", "taylor"]
複製代碼
注意: 修改person1.name的值,person2.name的值並未發生改變,並非由於person1和person2有獨立的name值,而是由於person1.name = 'person1',給person1添加了name值,並未修改了原型上的name值。對象
建立一個僅用於封裝繼承過程的函數,該函數在內部以某種形式來作加強對象,最後返回對象繼承
function createObj (o) {
var clone = object.create(o);
clone.sayName = function () {
console.log('hi');
}
return clone;
}
複製代碼
缺點 跟借用構造函數模式同樣,每次建立對象都會建立一遍方法。seo
爲了方便你們閱讀,在這裏重複一下組合繼承的代碼:
function Parent (name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
Parent.prototype.getName = function () {
console.log(this.name)
}
function Child (name, age) {
Parent.call(this, name);
this.age = age;
}
Child.prototype = new Parent();
var child1 = new Child('kevin', '18');
console.log(child1)
複製代碼
組合繼承最大的缺點是會調用兩次父構造函數。
一次是設置子類型實例的原型的時候:
Child.prototype = new Parent();
複製代碼
一次在建立子類型實例的時候:
var child1 = new Child('kevin', '18');
複製代碼
回想下new的模擬實現,其實在這句中,咱們會執行:
Parent.call(this, name);
複製代碼
在這裏,咱們又會調用了一次Parent構造函數。
因此,在這個例子中,若是咱們打印child1對象,咱們會發現Child.prototype和child1都有一個屬性爲color,屬性值爲["red", "blue", "green"]。
那麼咱們該如何避免這一次重複調用呢?
若是咱們不使用Child.prototype = new Parent(),而是直接的讓Child.prototype訪問到Parent.prototype呢? 👇
function Parent (name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.getName = function () {
console.log(this.name)
}
function Child (name, age) {
Parent.call(this, name);
this.age = age;
}
//關鍵的第3步
var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();
var child1 = new Child('kevin', '18');
console.log(child1);
複製代碼
最後咱們封裝一下這個繼承方法:
function object (o) {
function F () {}
F.prototype = o;
return new F();
}
function prototype(child, parent) {
var prototype = object(parent.prototype);
prototype.constructor = child;
child.prototype = prototype;
}
//使用
prototype(Child, Parent);
複製代碼
優勢