所谓的继承,本质上就是将子类的__proto__指向父类的prototype,我更倾向于叫它委托,因为父类并没有把自身的属性复制给子类,而只是给了子类使用的权限。子类调用父类的方法时,本质上还是通过查找原型链的方式进行调用。
当使用create方法创建对象时,也要注意
const obj = {
a: 2
}
const b = Object.create(obj) // 原理:把b的原型指向obj
一、原型继承:
function Foo (name) {
this.name = name;
};
Foo.prototype.myName = function () {
return this.name;
};
function Bar (name, label) {
Foo.call(this, name);
this.label = label;
};
Bar.prototype = Object.create(Foo.prototype);
const bar = new Bar('xiaoming', 'haoshuai');
Bar.prototype.myLabel = function () {
return this.label
}
提示:为什么不用 Bar.prototype = Foo.prototype,因为此时 Bar.prototype是对 Foo.prototype的引用,
当执行类似
Bar.prototype.myLabel = function () {
return this.label
}
的赋值语句时,会直接修改Foo.prototype对象本身,显然这不是想要的继承结果,否则直接使用Foo就可以了,根本不需要Bar对象。
这样做的唯一缺点就是需要创建一个新的对象然后把旧对象抛弃掉。
二、ES6之前,可以用__proto__方法来实现一个可靠并且标准的继承
function Foo (name) {
this.name = name;
};
Foo.prototype.myName = function () {
return this.name;
};
function Bar (name, label) {
Foo.call(this, name);
this.label = label;
};
Bar.prototype.__proto__ = Foo.prototype;
const b = new Bar('小明', '小矮子');
Bar.prototype.myLabel = function () {
return this.label;
}
console.log(Bar.prototype); // Foo {myLabel: ƒ, constructor: ƒ}
console.log(Foo.prototype); // {myName: ƒ, constructor: ƒ}
三、ES6的方法
Object.setPrototypeOf(Bar.prototype, Foo.prototype)
这种方式方法更短,可读性更高