js原型继承的几种方式 January 3, 2020 1. 原型链继承 2. 构造函数继承(对象冒充继承) 3. 组合继承(原型链继承+构造函数继承) 4. 原型式继承 5. 寄生组合式继承 ## 一。原型链继承 ``` function Show(){ this.name="run"; } function Run(){ this.age="20"; //Run继承了Show,通过原型,形成链条 } Run.prototype=new Show(); var show=new Run(); alert(show.name)//结果:run ``` ## 二。构造函数继承(对象冒充继承) 为了解决引用共享和超类型无法传参的问题,我们采用一种叫借用构造函数的技术,或 者成为对象冒充(伪造对象、经典继承)的技术来解决这两种问题 ``` function Box(age){ this.name=['Lee','Jack','Hello'] this.age=age; } function Desk(age){ Box.call(this,age); //对象冒充,给超类型传参 } var desk = new Desk(200); alert(desk.age);//200 alert(desk.name);//['Lee','Jack','Hello'] desk.name.push('AAA'); //添加的新数据,只给 desk alert(desk.name)//['Lee','Jack','Hello','AAA'] ``` ## 三。组合继承(原型链继承+构造函数继承) 借用构造函数虽然解决了刚才两种问题, 但没有原型, 复用则无从谈起。 所以, 我们需 要原型链+借用构造函数的模式,这种模式成为组合继承。 ``` function Box(age) { this.name = ['Lee', 'Jack', 'Hello'] this.age = age; } Box.prototype.run = function () { return this.name + this.age; }; function Desk(age) { Box.call(this, age); //对象冒充 } Desk.prototype = new Box(); //原型链继承 var desk = new Desk(100); alert(desk.run()); ``` ## 四。原型式继承 这种继承借助原型并基于已有的对象创建新对象, 同时还不必因此创建自定义类型 ``` function obj(o) { //传递一个字面量函数 function F() {} //创建一个构造函数 F.prototype = o; //把字面量函数赋值给构造函数的原型 return new F(); //最终返回出实例化的构造函数 } var box = { //字面量对象 name : 'Lee', arr : ['哥哥','妹妹','姐姐'] }; var box1 = obj(box); //传递 alert(box1.name); box1.name = 'Jack'; alert(box1.name); alert(box1.arr); box1.arr.push('父母'); alert(box1.arr); var box2 = obj(box); //传递 alert(box2.name); alert(box2.arr); //引用类型共享了 ``` ## 五。寄生组合式继承 寄生组合式继承解决了两次调用的问题,组合式继承就会有两次调用的情况 基本模型如下: ``` function object(o) { function F() {} F.prototype = o; return new F(); } function inheritPrototype(subType, superType) { var prototype = object(superType.prototype); //创建对象 prototype.constructor = subType; //增强对象 subType.prototype = prototype; //指定对象 } ```