js中所有的对象都是继承Object这个原型对象而来。javascript中没有继承的语法,其实现是通过原型链来连接对象与对象之间的关系。
原型链
- 每个对象都有
__proto__
属性,该属性指向其原型对象,在调用实例的方法和属性时,如果在实例对象上找不到,就会往原型对象上找
- 构造函数的
prototype
属性也指向实例的原型对象
- 原型对象的
constructor属性
指向构造函数
New实现
我们可以通过new可以创建一个对象,使用new的时候:
- 创建一个新对象;
- 这个对象的proto要指向构造函数的原型对象 ,
- 执行构造函数中的代码(为这个新对象添加属性)
- 如果构造函数返回值是对象则返回这个对象,如果不是对象则返回新的实例对象
function myNew(fn,...args){ var obj = {}; // 实现继承,实例可以访问函数的属性 var obj.__proto__ == fn.prototype; // 调用构造方法,并改变其 this 指向到实例 var res = fn.apply(obj, args); return typeof res === 'object' && res!== null ? res : obj;}
实现继承
原型链继承
直接让子类的原型对象指向父类实例,让子类实例找不到对应属性和方法时,就会往它的原型对象去找,从而实现了对父类属性和方法的继承
function Parent () { this.name = 'Thomas_H'}Parent.prototype.getName = function () { return this.name}// 子类function Child() {}// 让子类的原型对象指向父类实例, 这样一来在Child实例中找不到的属性和方法就会到原型对象(父类实例)上寻找Child.prototype = new Parent()Child.prototype.constructor = Child // 根据原型链的规则,顺便绑定一下constructor, 这一步不影响继承, 只是在用到constructor时会需要// 然后Child实例就能访问到父类及其原型上的name属性和getName()方法const child = new Child()child.name // 'Thomas_H'child.getName() // 'Thomas_H'