一、原型链继承
function ClassA() {} ClassA.prototype.color = "blue"; ClassA.prototype.sayColor = function () { alert(this.color); }; function ClassB() {} //继承ClassA的原型内容 ClassB.prototype = new ClassA();
这样ClassB的实例化对象b有个_prop_属性指向了ClassB.prototype,而其本身(ClassB.prototype)又是ClassA的实例化对象,所以,ClassB.prototype也有个_prop_属性指向了ClassA.prototype的原型对象,ClassA.prototype本身又是Object的实例化对象,有个_prop_属性指向了Object.prototype的原型对象,所以,都能使用继承链上所有prototype上的属性和方法。
注意:
1、原型链除了继承prototype的内容也能继承ClassA函数内的方法(注意:如果方法中含有this的引用,会出现undefined,可以通过对象冒充来解决该问题)
2、原型链不能将父类对象this改为子类对象this
3、如果要使用原型链,那么前提是父类是使用原型定义的
二、经典对象冒充方式
//父类 function Person(name,age) { this.name = name; this.age = age; this.show = function() { window.alert(this.name+"..."+this.age); } } Person.prototype.sayHi = function(){ alert("hi"); } //子类 function Student(name,age) { this.student = Person; //将Person类的构造函数赋值给this.student this.student(name,age); //js中实际上是通过对象冒充来实现继承的 delete this.student; //移除对Person的引用 } var s = new Student("小明",17); s.show(); //s.sayHi(); //对象冒充不能继承prototype内容 var p = new Person("小明",17); p.show(); p.sayHi(); //子类2 function MidStudent(name,age) { this.midstudent = Person; this.midstudent(name,age); //实现方法重载 this.show = function() { window.alert("midstudent show()"); } } var m = new MidStudent("张三",11); m.show();
三、call方式
/* call()方法是与经典的对象冒充方法最相似的方法 【第一个参数】用作 this 的对象。 【其他参数】直接传递给函数自身。 */ function sayColor(sPrefix,sSuffix) { alert(sPrefix + this.color + sSuffix); }; var obj = new Object(); obj.color = "blue"; //理解:将sayColor中原本的this替换成了obj的this //最后生成的消息 "The color is blue, a very nice color indeed." 将被显示出来 sayColor.call(obj, "The color is ", "a very nice color indeed.");
四、混合方式 call+原型链
function ClassA(sColor) { this.color = sColor; } //类1:给ClassA类加入sayColor方法 注意:对象冒充无法继承prototype加入的内容 ClassA.prototype.sayColor = function () { alert(this.color); }; //类2:使用对象冒充方式继承ClassA function ClassB(sColor, sName) { ClassA.call(this, sColor); this.name = sName; } //重点注意:这里是将ClassB的原型继承ClassA ClassB.prototype = new ClassA(); //给ClassB类加入sayName方法 ClassB.prototype.sayName = function () { alert(this.name); };