ECMAScript只支持继承,不支持接口实现,而实现继承的方式依靠原型链完成
原型+对象构造之间的关系结构,形成的像链条一样的,称之为原型链
1 //继承,通过原型链实现 2 function Box() //被继承的函数叫做超类型(父类 , 基类) 3 { 4 this.name ='Lee'; 5 } 6 7 function Desk() //继承的函数叫做子类型(子类,派生类) 8 { 9 this.age =100; 10 } 11 12 function Table() 13 { 14 this.level='AAAAA'; 15 } 16 17 //通过原型链继承,超类型实例化后的对象实例,赋值给子类型的原型属性 18 //new Box()会将Box构造里的信息和原型里的信息都交给Desk 19 //Desk的原型,得到的是Box的构造+原型里的信息 20 Desk.prototype =new Box(); 21 Table.prototype =new Desk(); 22 23 var desk =new Desk(); 24 alert(desk.name); //Lee 25 26 var table =new Table(); 27 alert(table.name); //Lee
★原型链+借用构造函数的模式,这种模式称为组合模式
1 //为了解决引用共享和超类型无法传参的问题,我们采用一种叫借用构造函数的技术,或者成为对象冒充(伪造对象、经典继承)的技术来解决这两种问题 2 3 function Box(name ,age) 4 { 5 this.name =name; 6 this.age = age; 7 this.family=['哥哥' , '姐姐' , '妹妹']; //引用类型,放在构造里面就不会被共享 8 } 9 10 Box.prototype.run =function() 11 { 12 return this.name + this.age +'运行中'; 13 } 14 15 //构造函数里的方法,放在构造函数里,每次实例化,都会分配一个内存地址,浪费,所以最好放在原型上 16 17 function Desk(name ,age) 18 { 19 Box.call(this,name ,age) //对象冒充 ★只能继承构造里面的信息 20 } 21 22 Desk.prototype =new Box(); //圆形链继承 23 24 var desk =new Desk('Lee' , 100); 25 alert(desk.run());
★原型式继承 单独使用并不方便,要和一下几种模式配合
1 //临时中转函数 2 function obj(o) //o表示将要传递进入的一个对象 3 { 4 function F(){}; //F构造是一个临时新建的对象,用来存储传递过来的对象 5 F.prototype =o; //将o对象实例赋值给F构造的原型对象 6 return new F(); //最后返回这个得到传递过来对象的对象实例 7 } 8 9 //F.prototype=o 其实就相当于 Desk.prototype = new Box(); 10 11 //这是字面量的声明方式,相当于var box =new Box(); 12 var box ={ 13 name:'Lee', 14 age:100, 15 family:['哥哥' , '姐姐' , '妹妹'] 16 }; 17 18 //box1就等于new F(); 19 var box1 =obj(box); 20 alert(box1.name); 21 alert(box1.family); //'哥哥' , '姐姐' , '妹妹' 22 box1.family.push('弟弟'); 23 alert(box1.family); //'哥哥' , '姐姐' , '妹妹' ,'弟弟' 24 25 var box2=obj(box); 26 alert(box1.family); //'哥哥' , '姐姐' , '妹妹' ,'弟弟' [引用类型的属性共享了]
★寄生式继承=原型式+工厂模式
1 //临时中转函数 2 function obj(o) 3 { 4 function F(){}; 5 F.prototype =o; 6 return new F(); 7 } 8 9 //寄生函数 10 function create(o) 11 { 12 var f =obj(o); //这里用obj(o); 13 f.run =function () //这里可以对f进行扩展 14 { 15 return this.name+'方法'; 16 } 17 return f; 18 } 19 var box ={ 20 name:'Lee', 21 age:100, 22 family:['哥哥' , '姐姐' , '妹妹'] 23 }; 24 25 var box1 =create(box); 26 alert(box1.run());
★★寄生组合继承[为了解决 组合式继承的 超类型会被两次调用的问题]
1 //临时中转函数 2 function obj(o) 3 { 4 function F(){}; 5 F.prototype =o; 6 return new F(); 7 } 8 9 //寄生函数 10 function create(box , desk) 11 { 12 var f =obj(box.prototype); 13 f.constructor=desk; //调整原型构造指针 14 desk.prototype=f; 15 } 16 17 function Box(name , age) 18 { 19 this.name =name; 20 this.age=age; 21 } 22 23 Box.prototype.run =function() 24 { 25 return this.name + this.age +'运行中...' 26 } 27 28 function Desk(name ,age) 29 { 30 Box.call(this, name ,age); 31 } 32 33 //通过寄生组合继承来实现继承 34 create(Box , Desk); 35 var desk =new Desk('Csn' ,100); 36 alert(desk.run()); 37 38 alert(desk.constructor);