Null's Blog

Javascript中的继承-原型链2

道格拉斯-克罗克福德在2006年写了一篇文章,大意介绍了一种实现继承的方法,这种方法并没有使用严格意义上的构造函数。他的想法是借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。这个是不是优点,可以有自己的判断:

1
2
3
4
5
function object(o){
function F(){}
F.prototype=o;
return new F();
}

在object()函数内部,先创建了一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例.从本质上讲,object()对传入其中的对象执行了一次浅复制.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var person={
name:"nUll",
friends:["gay1","gay2"]
};
var personA=object(person);
personA.name="mywei";
personA.friends.push("gay3");
var personB=object(person);
alert(personB.name); //nUll 来至原型
personB.name="nUll";
personB.friends.push("gay4");
alert(person.name); //nUll 来至原型
alert(personA.name); //mywei 来至personA 实例
alert(personB.name); //nUll 来至personB实例
alert(person.friends); //gay1,gay2,gay3,gay4 由于实例里不存在friends属性,所以这些改动都被直接记录到原型中的friends中了

ECMAScript5中新增了Object.create方法,规范化了原型式继承.这个方法接收两个参数:1作用新对象原型的对象;2一个为新对象定义额外属性的对象(可选),在传入一个参数的情况下Object.create()与object()方法的行为相同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var person={
name:"nUll",
friends:["gay1","gay2"]
};
var personA=Object.create(person);
personA.name="mywei";
personA.friends.push("gay3");
var personB=Object.create(person);
alert(personB.name); //nUll 来至原型
personB.name="nUll";
personB.friends.push("gay4");
alert(person.name); //nUll 来至原型
alert(personA.name); //mywei 来至personA 实例
alert(personB.name); //nUll 来至personB实例
alert(person.friends); //gay1,gay2,gay3,gay4 由于实例里不存在friends属性,所以这些改动都被直接记录到原型中的friends中了

第二个参数的用法:

1
2
3
4
5
6
7
8
9
10
var person={
name:"nUll",
friends:["gay1","gay2"]
};
var personA=Object.create(person,{
name:{
value:"mywei"
}
});
alert(personA.name); //mywei

包含引用类型值的属性始终都会共享相应的值,就像使用原型模式一样.