前言
最近一直在回顾js继承方式,在阅读《高级程序设计》第3版 的时候遇到一个问题,下面仅个人看法,如果有理解错误或者不同看法,欢迎一起探讨:
正文
何谓寄生组合继承,实质上分为两步:
- 将父类的原型对象赋值给子类的原型对象
- 将子类原型对象中的constructor指针指向子类构造函数
这样就实现了继承,具体代码如下所示(书中原代码):
function SuperType(name){
this.name = name;
}
SuperType.prototype.sayName = function(){
console.log(this.name);
}
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
function inheritPrototype(subType, superType){
const subPrototype = Object(superType.prototype);
subPrototype.constructor = SubType;
subType.prototype = subPrototype;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function(){
console.log(this.age);
}
const sub_1 = new SubType('liumin', '23');
sub_1.sayName();
sub_1.sayAge();
在inheritPrototype函数当中正是完成了上面的两个步骤,但是注意这里是通过Object函数创建一个对象赋值给subPrototype的,接下来我们了解一下Object函数
Object函数
为给定值创建一个对象包装器,如果传入的是undefined 或者 null,则返回一个空对象;否则返回一个给定值对应类型的对象;
console.log(Object(undefined));
console.log(Object(null));
console.log(Object('123'));
console.log(Object(123));
输出结果是:
如果传入的参数是一个对象,那么通过Object返回的则是对这个对象的引用,如下所示:
const person = {
name:'xiaohong',
age:'23',
grade:'12',
}
const anotherPerson = Object(person);
console.log(anotherPerson === person);
输出结果:
person和anotherPerson引用的是同一块内存地址,这与Object.create(obj)是有差别的,Object.create(obj)是在内存中新开辟一个空间
存在的问题
如果在上述的继承方式中存在一个问题,如果之后通过子类的原型对象对父类中的sayName方法进行重新定义,这时候就会修改父类中的sayName方法,从而继承父类的其他子类中的sayName方法也就会被篡改掉,造成混乱。
例如:
假如定义第二个子类——SubTypeCopy:
function SubTypeCopy(name, height){
SuperType.call(this, name);
this.height = height;
}
inheritPrototype(SubTypeCopy, SuperType);
然后在第一个子类中重新定义sayName方法:
SubType.prototype.sayName = function(){
console.log(`my name is:${this.name}`);
}
const sub_1 = new SubType('liumin', '23');
const sub_2 = new SubTypeCopy('liujie','180');
sub_1.sayName();
sub_2.sayName();
最后的输出结果是:
由此可以看出,SubTypeCopy中的sayName方法也发生了改变,如果将Object替换成Object.create(obj)方法,就不会存在这样的问题。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。