最近一直在回顾js继承方式,在阅读《高级程序设计》第3版 的时候遇到一个问题,下面仅我的见解,若是有理解错误或者不一样见解,欢迎一块儿探讨:函数
何谓寄生组合继承,实质上分为两步:this
这样就实现了继承,具体代码以下所示(书中原代码):spa
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函数prototype
为给定值建立一个对象包装器,若是传入的是undefined 或者 null,则返回一个空对象;不然返回一个给定值对应类型的对象;设计
console.log(Object(undefined)); console.log(Object(null)); console.log(Object('123')); console.log(Object(123));
输出结果是:指针
若是传入的参数是一个对象,那么经过Object返回的则是对这个对象的引用,以下所示:code
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)方法,就不会存在这样的问题。