有如下父类
function People(name,age){ this.name = name this.age = age this.seelp = function(){ console.log('i am seelp') } } People.prototype.eat = function(){ console.log('i can eat') }原理: 子类 的 prototype = 父类 的 实例 优点:
简单 不占用多余内存 父类实例化一次 原型属性继承
缺点:
无法对父类传递参数 在原型链上增加方法或者属性只能在实例化父类之后 无法实现多继承 非原型属性继承后无意义(undefined)
实现:
function Woman (name,age){ this.sex = '女'; } Woman.prototype = new People() Woman.prototype.constructor = Woman Woman.prototype.a = 'aaaa' var personal = new Woman('小丽','28') personal = { sex: "女", __proto__: { a: "aaaa", age: undefined, name: undefined, seelp: ƒ (), __proto__: Object } }原理: 在子类构造函数中,使用call修改父类的this指向 优点:
可像父类传递参数 可实现多继承 非原型属性继承 实现简单 方便新增属性
缺点:
原型属性无法继承 多占用内存(每个子类的实例,都调用了父类的实例)
function Woman(name,age){ People.call(this,name,age) Base.call(this,name,age) } var personal = new Woman('小丽','28') personal = { age: "28", jump: true, name: "小丽", seelp: ƒ (), __proto__:{ constructor: ƒ Woman(name,age) __proto__: Object } }原理: 调用父类构造函数,继承父类的属性,通过将父类实例作为子类原型,实现函数复用 优点:
可像父类传递参数 可实现多继承 非原型属性继承 原型属性继承
缺点:
多占用内存(每个子类的实例,都调用了父类的实例)
function Woman(name,age){ People.call(this,name,age) } Woman.prototype = new People(); Woman.prototype.constructor = Woman; var personal = new Woman('小刘鸭','27') personal = { age: 27, name: "小刘鸭", seelp: ƒ(), __proto__: { age: undefined, constructor: Woman, name: undefined, seelp: ƒ(), __proto__: Object } }原理: 子类的原型不再是父类的实例,而是空类,空类的原型指向父类的原型, 优点:
可像父类传递参数 可实现多继承 非原型属性继承 原型属性继承
function Woman(name,age){ //继承父类属性 People.call(this,name,age) } //继承父类方法 (function(){ // 创建空类 let Super = function(){}; Super.prototype = People.prototype; //父类的实例作为子类的原型 Woman.prototype = new Super(); })(); //修复构造函数指向问题 Woman.prototype.constructor = Woman; var personal = new Woman('小刘鸭',27) personal = { age: 27, name: "小刘鸭", seelp: ƒ(), __proto__: { constructor: Woman(name, age), __proto__: { eat: ƒ(), constructor: People(name, age), __proto__: Object } } }