Null's Blog

Javascript中的继承-借用构造函数

上篇:

1
2
3
4
5
6
7
8
9
10
11
12
13
function SuperType(){
this.friends=["gay1","gay2"];
}
function SubType(){
}
SubType.prototype=new SuperType();
var instance1=new SubType();
var instance1.friends.push("gay3");
alert(instance1.friends);
var instance2=new SubType();
alert(instance2.friends);
alert(instance1 instanceof SuperType); //true
//gay1,gay2,gay3 这个实例里为什么会有gay3 可以简单解释为 SuperType中的friends是instance1和instance2所在的作用域链共享的

在创建子类型的实例时,不能向父类的构造函数中传递参数,更确切的表述为:没有办法在不影响所有对象实例的情况下,给父类的构造函数传递参数.
为什么无法传参? 可以自己试试,看看是否能实现.
因此,一般情况下很少单独使用原型链实现继承.
现在介绍”借用构造函数”实现继承的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//构造函数无参数
function SuperType(){
this.friends=["gay1","gay2"];
}
function SubType(){
SuperType.call(this); //这样实现了继承 与上段代码的继承方式有什么不同?
}
var instance1=new SubType();
var instance2=new SubType();
instance1.friends.push("gay3");
alert(instance1.friends); //gay1,gay2,gay3
alert(instance2.friends); //gay1,gay2
//-----------------------------邪恶的分割线-------------------------//
//构造函数有参数
function SuperType(name){
this.name=name;
}
function SubType(name){
SuperType.call(this,name); //等同于SuperType.apply(this,[name]) 或 SuperType.apply(this,arguments)
}
var instance1=new SubType("nUll");
var instance2=new SubType("mywei");
alert(instance1.name); //nUll
alert(instance1.name); //mywei
alert(instance1 instanceof SuperType); //false

这里虽然使用call方法实现继承的基本目的,可是instance1却不是SuperType的实例了(上面最后一行),对比下本文开始的一段代码.所以,上面这段代码本质是:在SubType创建实例的时候调用了SuperType的构造函数(在实例的独立的作用域链内),严格来说,SuperType并不是SubType的父类.
这只是借用了”父类”SuperType的构造函数而已(可参照另一片文章).所以,这种方式又被称为“伪造对象“或“经典继承”.