原文地址:http://www.hoverlees.com/blog/?p=1193
javascript的prototype在新对象创建时会复制这个类的prototype到新的实例,但要注意,它不会完全复制值是对象的属性,而是复制对象的指针。另一方面,这样可以达到面象对象中的静态变量效果。
如下面的示例代码所示:
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
27
28
29
30
|
function
A(num){
this
.num=num;
this
.inner.instanceNum++;
}
A.prototype={
num:0,
inner:{
instanceNum:0,
invokeNum:0
},
setNum:
function
(num){
this
.num=num;
this
.inner.invokeNum++;
},
toString:
function
(){
return
"Num:"
+
this
.num+
" instanceNum:"
+
this
.inner.instanceNum+
" setNum:"
+
this
.inner.invokeNum;
}
};
var
a=
new
A(10);
var
b=
new
A(20);
var
c=
new
A(30);
a.setNum(100);
b.setNum(200);
b.setNum(200);
c.setNum(300);
c.setNum(300);
c.setNum(300);
alert(a);
alert(b);
alert(c);
|
这段代码咋一看,执行完成后所有对象inner.instanceNum都应该等于1,a的inner.invokeNum=1,b的是2,c的是3
而程序的真正输出是
Num:100 instanceNum:3 setNum:6
Num:200 instanceNum:3 setNum:6
Num:300 instanceNum:3 setNum:6
所以如果使用prototype方式的面向对象编程,在原型的定义里,属性的值不能是对象,否则它相当于标准面象对象里的静态变量了(但这正好是js的静态变量定义方式呢)
正确的方式应该是在构造函数里声明对象,如下
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
27
28
29
30
31
|
function
A(num){
this
.num=num;
this
.inner={
instanceNum:0,
invokeNum:0
};
this
.inner.instanceNum++;
}
A.prototype={
num:0,
inner:
null
,
setNum:
function
(num){
this
.num=num;
this
.inner.invokeNum++;
},
toString:
function
(){
return
"Num:"
+
this
.num+
" instanceNum:"
+
this
.inner.instanceNum+
" setNum:"
+
this
.inner.invokeNum;
}
};
var
a=
new
A(10);
var
b=
new
A(20);
var
c=
new
A(30);
a.setNum(100);
b.setNum(200);
b.setNum(200);
c.setNum(300);
c.setNum(300);
c.setNum(300);
alert(a);
alert(b);
alert(c);
|