1.组合继承
function Parent(name) { this.name = name; } Parent.prototype.getValue = function() { console.log(this.val) } function Son(name) { Parent.call(this, name); //继承属性 this.A = function a(){} } Son.prototype = new Parent(); //继承方法
缺点就是在继承父类函数的时候调用了父类构造函数,导致子类的原型上多了不需要的父类属性,存在内存上的浪费。创建实例时,相当于调用了两次父类的构造函数,使得实例属性和原型链上属性重复。
2.寄生组合继承
function Parent(name) { this.name = name; } Parent.prototype.getValue = function() { console.log(this.val) } function Son(name) { Parent.call(this, name); //继承属性 } Son.prototype = Object.create(Parent.prototype); //继承方法 Son.prototype.constructor = Son; //把构造函数指向子类构造函数。
3.class继承
class Son extends Parent { constructor(name) { super(name); } A() { } }
call apply bind
都是为了解决this指向的问题。
call和apply传入的参数不同
getValue.call(a, 'yck', '24')
getValue.apply(a, ['yck', '24'])
call和apply是立即执行,bind是返回一个this固定的函数。
手写bind
Function.prototype.bind1 = function() { const args = Array.prototype.slice.apply(arguments) const t = args.shift() const self = this return function() { return self.apply(t, args) } }
手写apply
Function.prototype.apply1 = function() { let context = argments[0] context.fn = this let result; if(arguments[1]) { result = context.fn(...argments[1]) } else { result = context.fn() } delete context.fn return result; }