1

前言

最近一直在回顾js继承方式,在阅读《高级程序设计》第3版 的时候遇到一个问题,下面仅个人看法,如果有理解错误或者不同看法,欢迎一起探讨:

正文

何谓寄生组合继承,实质上分为两步:

  1. 将父类的原型对象赋值给子类的原型对象
  2. 将子类原型对象中的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)方法,就不会存在这样的问题。


maxmin
226 声望6 粉丝

« 上一篇
Array的迭代器