继承的几种方式
//继承:通过原型链继承 //继承是面向对象中一个比较核心的概念。其他正统面向对象语言都会用两种方式实现继承:一个是接口实现,一个是继承。而ECMAScript只支持继承,不支持接口实现,而实现继承的方式依靠原型链完成。 //1 原型链继承 function Box(){ this.name = "lee"; } function Desk(){ this.age = 100; } Desk.prototype.age = 200; function Table(){ this.level = "aaaa"; } Desk.prototype = new Box(); //Desk继承了Box Table.prototype = new Desk(); //Table继承了Desk和Box var desk = new Desk(); alert(desk.name); //lee var table = new Table(); alert(table.name); //lee //如果要实例化table,那么Desk实例中有age=100,原型中增加相同的属性age=200,最后结果是多少呢? alert(table.age); //100,还是就近原则 //缺点:无法传参,引用共享,解决办法:对象冒充 //2 经典继承:借用构造函数或称为对象冒充继承 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"); alert(desk.name); //lee,jack,hello,AAA var desk2 = new Desk(300); alert(desk2.name); //lee,jack,hello //缺点:借用构造函数虽然解决了刚才两种问题,但没有原型,复用则无从谈起。 //4 组合继承:原型链+借用构造函数。 //组合式继承是JavaScript最常用的继承模式;但,组合式继承也有一点小问题,就是超类型在使用过程中会被调用两次:一次是创建子类型的时候,另一次是在子类型构造函数的内部。寄生继承将解决这个问题 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); //对象冒充 , 第二次调用Box } Desk.prototype = new Box(); //原型链继承 var desk = new Desk(100); //第一次调用Box alert(desk.run()); //4 原型式继承:这种继承借助原型并基于已有的对象创建新对象,同时还不必因此创建自定义类型。 function obj(o){ //传递一个字面量函数 function F(){} //创建一个构造函数 F.prototype = o; //吧字面量函数赋值给构造函数原型 return new F(); //最终返回出实例化的构造函数 } var box = { //字面量对象 name:"lee", arr:['gege','meimei','jiejie'] } 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); //引用类型共享了 //5 寄生式继承:原型式+工厂模式,目的是封装创建对象过程 function obj(o) { function F() {} F.prototype = o; return new F(); } function create(box, desk) { var f = obj(box.prototype); f.constructor = desk; desk.prototype = f; } function Box(name) { this.name = name; this.arr = ['哥哥','妹妹','父母']; } Box.prototype.run = function () { return this.name; }; function Desk(name, age) { Box.call(this, name); this.age = age; } inPrototype(Box, Desk); //通过这里实现继承 var desk = new Desk('Lee',100); desk.arr.push('姐姐'); alert(desk.arr); alert(desk.run()); //只共享了方法 var desk2 = new Desk('Jack', 200); alert(desk2.arr); //引用问题解决
本博客作为一个入门者的自学记录,欢迎各位同行者不吝赐教。