前置
- 所有的对象都是__proto__属性,指向其构造函数的原型对象
- 所有的函数对象都有prototype属性表示原型对象,作用:共享实例对象的属性和方法.
构造函数绑定
Parent.apply(this,arguments) // this是子类实例,调用父类,即可拿到其属性和方法
prototype模式
Child.prototype = new Parent() // 子类的原型对象是父类的实例
Child.prototype.constructor = Child // 原型对象都有constructor属性,修改prototype指向后一定要修正构造函数
直接继承prototype
Child.prototype = Parent.prototype // 子类原型对象指向父类原型对象,减少调用次数
Child.prototype.constructor = Child
- 优点:效率高,省内存,不需要建立父类的实例
- 缺点:父类和子类的原型对象指向同一个值,修正constructor指向的代码同时修改了父类原型对象的构造函数指向
利用空对象作为中介
function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
}
- F是空对象,几乎不占内存
拷贝继承
- 把父对象的所有属性和方法拷贝到子对象中
function extend2(Child, Parent) {
var p = Parent.prototype;
var c = Child.prototype;
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
}
object()函数
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
拷贝
function deepCopy(p, c) {
var c = c || {};
for (var i in p) {
if (typeof p[i] === 'object') {
c[i] = (p[i].constructor === Array) ? [] : {};
deepCopy(p[i], c[i]);
} else {
c[i] = p[i];
      }
}
return c;
}
ES5继承:先创造子类的实例对象this,然后再将父类的方法添加到this上面
ES6
- class+extend+constructor+super
先创建父类实例this 通过class丶extends丶super关键字定义子类,并改变this指向,super本身是指向父类的构造函数但做函数调用后返回的是子类的实例,实际上做了父类.prototype.constructor.call(this),做对象调用时指向父类.prototype,从而实现继承。
参考链接:
Javascript面向对象编程(二):构造函数的继承
Javascript面向对象编程(三):非构造函数的继承
ES5和ES6及继承机制