js中所有的对象都是继承Object这个原型对象而来。javascript中没有继承的语法,其实现是通过原型链来连接对象与对象之间的关系。

原型链

  1. 每个对象都有__proto__属性,该属性指向其原型对象,在调用实例的方法和属性时,如果在实例对象上找不到,就会往原型对象上找
  2. 构造函数的prototype属性也指向实例的原型对象
  3. 原型对象的constructor属性指向构造函数

New实现

我们可以通过new可以创建一个对象,使用new的时候:

  1. 创建一个新对象;
  2. 这个对象的proto要指向构造函数的原型对象 ,
  3. 执行构造函数中的代码(为这个新对象添加属性)
  4. 如果构造函数返回值是对象则返回这个对象,如果不是对象则返回新的实例对象
  1. function myNew(fn,...args){
  2. var obj = {};
  3. // 实现继承,实例可以访问函数的属性
  4. var obj.__proto__ == fn.prototype;
  5. // 调用构造方法,并改变其 this 指向到实例
  6. var res = fn.apply(obj, args);
  7. return typeof res === 'object' && res!== null ? res : obj;
  8. }

实现继承

原型链继承

直接让子类的原型对象指向父类实例,让子类实例找不到对应属性和方法时,就会往它的原型对象去找,从而实现了对父类属性和方法的继承

  1. function Parent () {
  2. this.name = 'Thomas_H'
  3. }
  4. Parent.prototype.getName = function () {
  5. return this.name
  6. }
  7. // 子类
  8. function Child() {}
  9. // 让子类的原型对象指向父类实例, 这样一来在Child实例中找不到的属性和方法就会到原型对象(父类实例)上寻找
  10. Child.prototype = new Parent()
  11. Child.prototype.constructor = Child // 根据原型链的规则,顺便绑定一下constructor, 这一步不影响继承, 只是在用到constructor时会需要
  12. // 然后Child实例就能访问到父类及其原型上的name属性和getName()方法
  13. const child = new Child()
  14. child.name // 'Thomas_H'
  15. child.getName() // 'Thomas_H'