ECMAScript只支持继承,不支持接口实现,而实现继承的方式依靠原型链形成。
1.使用原型链继承
function Box() { //被继承的函数叫做超类型(父类,基类) this.name = 'Lee'; } function Desk() { //继承的函数叫做子类型(子类,派生类) this.age = 100; } function Table() { this.level = 'AAAAA'; } //通过原型链继承,超类型实例化后的对象实例,赋值给子类型的原型属性 //new Box()会将Box构造里的信息和原型里的信息都交给Desk //Desk的原型,得到的是Box的构造+原型里的信息 Desk.prototype = new Box(); Table.prototype = new Desk(); var box = new Box(); alert(box.constructor); var desk = new Desk(); //alert(desk.age); //alert(desk.name); var table = new Table(); //alert(table.level); //alert(desk.age); //alert(desk.name);
function Box() { //被继承的函数叫做超类型(父类,基类) this.name = 'Lee'; } Box.prototype.name = 'Jack'; function Desk() { //继承的函数叫做子类型(子类,派生类) this.age = 100; } Desk.prototype = new Box(); //通过原型链继承 var box = new Box(); var desk = new Desk(); //alert(desk.name); //就近原则,实例里有,就返回,没有就去查找原型 //子类型从属于自己或者他的超类型 //alert(desk instanceof Object); alert(desk instanceof Desk); alert(desk instanceof Box); alert(box instanceof Desk);
2.借用构造函数继承(使用对象冒充继承)
function Box(name, age) { this.name = name; this.age = age; this.family = ['哥哥','姐姐','妹妹']; //引用类型,放在构造里就不会被共享 } //Box.prototype.family = '家庭'; function Desk(name, age) { Box.call(this, name, age) //对象冒充,对象冒充只能继承构造里的信息 } var desk = new Desk('caibaojian', 100); alert(desk.family); desk.family.push('弟弟'); alert(desk.family); //哥哥,姐姐,妹妹,弟弟 var desk2 = new Desk('caibaojian', 100); alert(desk2.family);//不会共享属性,哥哥,姐姐,妹妹
3.我们需要原型链+借用构造函数的模式,这种模式称为组合继承
function Box(name, age) { this.name = name; this.age = age; this.family = ['哥哥','姐姐','妹妹']; } Box.prototype.run = function () { return this.name + this.age + '运行中...'; }; //构造函数里的方法,放在构造里,每次实例化,都会分配一个内存地址,浪费,所以最好放在原型里,保证多次实例化只有一个地址 function Desk(name, age) { Box.call(this, name, age) //对象冒充 } Desk.prototype = new Box(); //原型链继承(因为对象冒充只能继承构造里的信息,所以原型需要加上原型) var desk = new Desk('Lee', 100); alert(desk.run());