Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

js基础之继承 #37

Open
jerryni opened this issue Apr 11, 2022 · 1 comment
Open

js基础之继承 #37

jerryni opened this issue Apr 11, 2022 · 1 comment
Labels

Comments

@jerryni
Copy link
Owner

jerryni commented Apr 11, 2022

原型链继承的2个问题

如果属性包含引用类型,那么不同的实例之间会共享同一个属性。如下:

function SuperType() {
  this.colors = ['red'];
}
function SubType() {}

// 继承
SubType.prototype = new SuperType();
let instance1 = new SubType();
instance1.colors.push('black');
console.log(instance1.colors); // ['red', 'black']
let instance2 = new SubType();
console.log(instance2.colors); // ['red', 'black']

第二个问题是:

没法在不影响所有对象实例的情况下,向父类型的构造函数中传递参数;

借用构造函数

借用构造函数用来解决上面的两个问题

function SuperType(name) {
  this.name = name;
}
function SubType() {
  // 借用构造函数
  SuperType.call(this, 'foo');

  // 实例属性,最好在调用了上面的语句之后设置,防止被父构造函数覆盖属性;
  this.age = 29;
}

const instance = new SubType();
console.log(instance); // { name: 'foo', age: '29' }
// 去掉下面这句
// SubType.prototype = new SuperType();

组合继承

这目前是Javascript最常用的继承模式;
原型链 + 借用构造函数的合体;

1

缺点:
会调用两次父类型的构造函数... 后面的寄生组合式继承是可以解决这个问题的

原型式继承

这个继承方式算是简化版的继承,要求你必须有一个对象作为另一个对象的基础;
缺点是会有浅拷贝的问题;
Object.create()其实就是规范化后的原型式继承;

Object

寄生式继承

这感觉就是原型式继承的工厂模式...没啥好说的
2
3

缺点:

跟构造函数模式一样,不能做到函数复用而降低效率;

寄生组合式继承(最完美的方案)

为了解决组合式继承的调用两次构造函数的问题,在原型链继承赋值的时候进行了优化;

原句:

不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已;

// 传入两个构造函数
function inheritPrototype(subType, superType) {
  // 一个父类型的原型副本
  let prototype = Object.create(superType.prototype);
  // 防止constructor丢失
  prototype.constructor = subType;
  // 赋值
  subType.prototype = prototype; 
}

5

总结

最完美的解决方案是 组合寄生式继承;

  1. 在构造函数里通过.call调用父构造函数继承属性;
  2. 通过Object.create()拷贝父原型,然后继承父类的方法;

参考

Javascript高级程序设计(第3版)

@jerryni jerryni changed the title javascript之继承 js基础之继承 Apr 11, 2022
@jerryni jerryni added the js label Apr 11, 2022
@jerryni
Copy link
Owner Author

jerryni commented Apr 11, 2022

一个小思考

es6里的class extends关键字在babeljs里是怎么实现的?

1
2

妥妥的寄生组合式继承!:+1::beer:

在线链接

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant