function SuperType() {
this.property =true;
}
SuperType.prototype.getSuperValue =function() {
returnthis.property;
}
function SubType() {
this.subproperty =false;
}
//发生继承行为
SubType.prototype =new SuperType();
SubType.prototype.getSubValue =function() {
returnthis.subproperty;
}
var instance =new SubType();
alert(instance.getSuperValue()); //true
alert(instance instanceofObject); //true
alert(instance instanceof SuperType); //true
alert(instance instanceof SubType); //true
alert(Object.prototype.isPrototypeOf(instance)); //true
alert(SuperType.prototype.isPrototypeOf(instance)); //true
alert(SubType.prototype.isPrototypeOf(instance)); //true
代码中,重写了SubType的原型,而不是用原来默认的。由于property是一个实例属性,getSuperValue是一个原型方法。所以property会出现在SubType Prototype(SuperType的实例)中,而getSuperValue不会出现。instance的constructor现在只想的SuperType。
还有一个要提及的是,Javascript中,所有的函数默认的原型都是Object的实例,SuperType函数的prototype也是指向Object Prototype。 因此通过这样一个链条访问属性的时候,还是会通过搜索机制顺藤摸瓜的找到对应的属性。
原型链的缺点很明显,所有的子类的属性是共享的。这个缺点是致命的,因此实践中很少单独使用原型链。
call/apply方法这种方法称为constructor stealing(借用构造函数)。
call方法的作用,官方解释 call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明: call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。 如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
我的理解,就是把原有对象中的代码,放到thisObj中运行,代码中如果出现this,代表的就是thisObj中。
举个例子:
function Animal(){
this.name = "Animal";
this.showName = function(){
alert(this.name);
}
}
/**定义一个Cat类*/
function Cat(){
this.name = "Cat";
}
/**创建两个类对象*/
var animal = new Animal();
var cat = new Cat();
//通过call或apply方法,将原本属于Animal对象的showName()方法交给当前对象cat来使用了。
//输入结果为"Cat"
animal.showName.call(cat,",");
//animal.showName.apply(cat,[]);
关于call和apply方法的概念,可以自行网上查阅,其中call和apply的差别在于调用时候的参数。 call调用时,参数为用逗号分隔的一组值,而apply调用的时候,参数为是一个数组,一个记忆方式为,C对应comma,A对应Array。 call的主要运用场景就是在面向对象值的模拟继承关系。
例子:
function SuperType(){
this.colors = ["red", "blue", "green"];
}
function SubType(){
//继承了SuperType
SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green"
代码中,通过call方法,在SubType中,借用了SuperType中的函数的代码,以此来为完善自己的属性。这就导致SubType中的实例都有了自己的colors属性。 这种方式可以在子类的构造方法调用中输入参数。
function SuperType(name)
{
this.name= name;
}
function SubType(){//继承了SuperType,并且传递了参数
SuperType.call(this,"zhangsan");
this.age=20;
}
var instance=new SubType();
alert(instance.name) //zhangsan
alert(instance.age) //20
当然,这种方式也存在缺点,方法都在构造函数中定义,并没有真正复用。