下面举例来说说继承关系,看看对象都拥有哪些方法。
1,构造函数继承
function SuperClass() {
this.name = 1;
this.print = function() {
alert("print super");
}
}
function SubClass() {
this.super = SuperClass;
this.super();
delete this.super;
}
SuperClass和SubClass可以看成是两个类,SuperClass通过new出来的对象具有name属性和print方法。
如:var super = new SuperClass();super.print()
SubClass构造体里将SuperClass作为他的一个成员方法,并且执行了该方法,使得SubClass构造出来的实例拥有了SuperClass中的print方法和name属性。
delete this.super是删除这个对象的super属性,使对象对此方法没有访问权限。
2,对象冒称继承--通过call或者apply方法实现
function SuperClass() {
this.name = 1;
this.print = function() {
alert("print super");
}
}
function SubClass() {
SuperClass.call(this)
}
SubClass中SuperClass.call(this)是指调用下SuperClass这个方法,用call的第一个参数去冒称SuperClass里的this对象,call方法第二个参数和之后的参数对应SuperClass函数接收的参数。如SuperClass.call(this,param,param2)。SubClass中SuperClass.call(this)也可以换成SuperClass.apply(this)。apply的意思call的意思基本上是一致,区别在于apply是用数组接收参数,如SuperClass.apply(this,[param,param2])。call,apply只有通过function关键字或Function创建出来的方法对象、Function、Object能调用。
3,prototype原型对象继承
prototype对象和call、apply方法都是javascript内部特有的,prototype也是只有通过function关键字或Function创建出来的方法对象、Function、Object能调用的属性。
function SuperClass() {
this.name = 1;
this.print = function() {
alert("print super");
}
}
SuperClass.prototype.say = function() {
alert(this.name);
}
这样SuperClass构造出来的实例就拥有了say这个方法。因为构造出来的实例在执行say方法时是先从SuperClass构造体中找,找到的话就执行构造体中的say方法,否则就从
SuperClass的prototype对象中找,默认情况下prototype对象是一个Object的实例相当于new Object()或{}。
function SuperClass() {
this.name = 1;
this.print = function() {
alert("print super");
}
}
SuperClass.prototype.say = function() {
alert(this.name);
}
function SubClass() {
this.subname = 2;
}
SubClass.prototype = new SuperClass();
按照上面分析,SubClass方法构造出来的对象除了有subname这个属性,还将继承SubClass.prototype对象中的属性和方法,也就是具备name、print、say等属性和方法。
Function.prototype = {
arg:3,
all:function(){
alert("所有的方法都有这个all方法和arg属性"+this.arg);
}};
function SuperClass() {
this.name = 1;
this.print = function() {
alert("print super");
}
}
SuperClass.prototype.say = function() {
alert(this.name);
}
function SubClass() {
this.subname = 2;
}
SubClass.prototype = new SuperClass();
//测试:
SuperClass.all();
SubClass.all();
Function.all();
Object.all();
按照javascript原型继承法的特点,function关键字或Function创建出来的方法都是Function(他本身也是function)构造出来的实例,如果给Function.prototype注入些方法或属性的话,那么所有的方法都将具有这些方法或属性。
给Function的prototype添加了all方法后,就所有的方法都有all方法,Function和Object本身也是方法,所以他们也有all方法
Object.prototype = {
arg:3,
all:function(){
alert("所有的方法都有这个all方法和arg属性"+this.arg);
}};
function SuperClass() {
this.name = 1;
this.print = function() {
alert("print super");
}
}
SuperClass.prototype.say = function() {
alert(this.name);
}
function SubClass() {
this.subname = 2;
}
SubClass.prototype = new SuperClass();
//测试:
SuperClass.all();
SubClass.all();
Function.all();
Object.all();
new SuperClass().all();
new SubClass().all();
如果要让所有对象都具备这样的all的方法就给Object的Prototype注入方法。
上例中SuperClass构造出来的实例也拥有all方法。
javascript的继承是用一个对象继承另外一个对象所拥有的属性和方法,跟被继承的对象的构造器没有很直接的关系。因为对象的方法构造器只是决定这个对象创建时所具有的初始属性和方法,而这个对象在以后是可以被修改所拥有的属性和方法(如删除或增加这个对象的某个方法或属性),这就是javascript的动态性,javascript定义变量或传参时并不需要定义参数的具体类型(javascript的弱类型),javascript在运行中验证数据。