先构造一个 parent
function Person(name) {
this.name = name;
this.hobby = ["painting"];
}
Person.prototype.job = "frontend";
Person.prototype.sayHello = function() {
console.log("Hello " + this.name);
}
一、原型链继承
function Child() {
this.name = "child";
}
Child.prototype = new Person();
let child = new Child();
这种方法不能向 parent 传参
而且引用类型的属性被所有实例共享,如下图:
二、借用构造函数
function Child() {
Person.call(this, "duolaameng")
}
let child = new Child();
这种方法可以向 parent 传参
可以实现多继承
而且这种方法避免了引用类型被实例共享
这种方法每个子类都有父类实例函数的副本,影响性能
它也不能继承原型上的属性
三、组合继承
就是 原型链继承 + 构造函数继承
function Child(name) {
Person.call(this, name)
}
Child.prototype = Person.prototype;
let child = new Child("duolaameng");
这种方法融合了原型链继承和构造函数的优点:
可以向 parent 传参
继承了原型上的属性
避免了引用类型被实例共享:
四、原型式继承
function createObj(o) {
function F(){ };
F.prototype = o;
return new F();
}
这种方式是将传入的对象作为创建对象的原型
本质上是对传入的参数 o 进行了一次浅拷贝
这也是 object.create() 的原理
这种方法也会有引用共享的问题:
五、寄生模式继承
function createAnother(o) {
var clone = Object.create(o);
clone.sayHi = function () {
console.log("hi");
};
return clone;
}
let person = new Person("Cindy");
var child = createAnother(person);
六、寄生组合式继承
function inheritPrototype(Child, Parent) {
let prototype = Object.create(Parent.prototype);
prototype.constructor = Child;
Child.prototype = prototype;
}
function Child(name, job) {
Person.call(this, name);
this.job = job;
}
inheritPrototype(Child, Person)
let child = new Child("Cindy", "FE");
child.sayHello();
这个方法在前面原型链学习文集中的圣杯模式实现继承中加了调用父类构造函数的功能
七、ES6 的 Object.setPrototypeOf
ES6 提供了可以设置原型的方法
function Child(name) {
this.name = name;
}
Object.setPrototypeOf(Child.prototype, Person.prototype);
let child = new Child("name");
注意
constructor 是 Child 哦!








网友评论