segmentfault官方|ES5 继承( 三 )


functionF{}
F.prototype = o;
returnnew F;
}
返回新对象 , 让其原型指向O
letperson = {
name: "Nicholas",
【segmentfault官方|ES5 继承】friends: [ "Shelby", "Court", "Van"],
};
letanotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push( "Rob");
letyetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push( "Barbie");
console.log(person.friends);
// "Shelby,Court,Van,Rob,Barbie";
父对象中的引用属性会在子对象中共享 , 导致相互污染 。
ES5引入了Object.create规范了原型式继承 。
letperson = {
name: "Nicholas",
friends: [ "Shelby", "Court", "Van"],
};
letanotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push( "Rob");
letyetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push( "Barbie");
console.log(person.friends);
// "Shelby,Court,Van,Rob,Barbi
使用Object.create后anotherPerson.__proto__===person成立 , 所以anotherPerson可以拿到person的属性 , 但是同样存在父对象属性共享的问题 , 改了父对象的属性 , 其他的子对象都跟着改变 。
劣势:
父对象的引用类型会在实例中共享 , 这样就会相互污染 。
寄生式继承
寄生式继承跟原型式继承很类似 , 用工厂函数在对返回的新对象包一层 , 给新对象赋值一些属性
工厂函数的定义:
functioncreateAnother(original) {
letclone= object(original);
// 通过调用函数创建一个新对象;
clone.sayHi = function{
// 以某种方式增强这个对象;
console.log( "hi");
};
returnclone; // 返回这个对象
}
使用:
letperson = {
name: "Nicholas",
friends: [ "Shelby", "Court", "Van"],
};
letanotherPerson = createAnother(person);
anotherPerson.sayHi; // "hi"
定义在新对象上的sayHi方法 , 每次调用新对象都是新的 , 无法实现共享 。
劣势:

  • 父对象的引用类型会在实例中共享 , 这样就会相互污染 。
  • 方法无法实现共享
寄生式组合继承
上面提到 , 组合继承的缺点就是父类构造函数会被调用两次 , 一次是在子类的构造函数中 , 另一次在创建子类原型时调用 。 继承就是要继承父类的属性跟方法 , 组合继承实现了这个目标 , 但是怎么避免重复调用父类构造函数 。
先看下组合继承:
functionSuperType(name) {
this.name = name;
this.colors = [ "red", "blue", "green"];
}
SuperType.prototype.sayName = function{
console.log(this.name);
};
functionSubType(name, age) {
SuperType.call(this, name); // 第二次调用 , 将父类的属性绑定到子类的实例中
SuperType;
this.age = age;
}
SubType.prototype = new SuperType;
// 第一次调用SuperType;
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function{
console.log(this.age);
};
segmentfault官方|ES5 继承
本文插图


推荐阅读