Javascript原型继承中的诡异现象和解释


Javascript的继承采用的是原型继承方式,即使用某个构造函数生成的对象可以使用这个构造函数的原型对象的方法。

好了,熟悉JS的人都知道上面这个事实,下面我们来看一个诡异的问题。

先看这段代码:

 1 var ProtoTypeClazz = function(){
2 this.arr = [];
3 }
4
5 ProtoTypeClazz.prototype.add = function(){
6 this.arr.push("testData");
7 }
8
9 ProtoTypeClazz.prototype.print = function(){
10 alert(this.arr);
11 }
12
13 var Clazz = function(){}
14 Clazz.prototype = new PrototypeClazz();
15
16 var obj1 = new Clazz();
17 obj1.add();
18 obj1.print();//输出testData
19
20 var obj2 = new Clazz();
21 obj2.add();
22 obj2.print();//输出testData,testData

上述这个代码熟悉JS的人都很理解,每个ProtoTypeClazz类型的对象有一个名为arr的数组变量。obj1和obj2共享一个ProtoTypeClazz类型的对象,这个对象在第14行生成。obj1和obj2的操作都是对这个对象进行操作,所以两次add方法的效果叠加,第一次print输出testData,第二次输出testData,testData

那么我们来看一下下面一段代码:

 1 var ProtoTypeClazz = function(){
2 this.value = 1;
3 }
4
5 ProtoTypeClazz.prototype.add = function(){
6 this.value++;
7 }
8
9 ProtoTypeClazz.prototype.print = function(){
10 alert(this.value);
11 }
12
13 var Clazz = function(){}
14 Clazz.prototype = new PrototypeClazz();
15
16 var obj1 = new Clazz();
17 obj1.add();
18 obj1.print();//输出2
19
20 var obj2 = new Clazz();
21 obj2.add();
22 obj2.print();//输出2

这段代码和上一段代码不同的地方是,每个ProtoTypeClazz对象中保存的变量是一个名叫value的基础类型变量。上一段代码保存的是一个数组。

奇怪的地方来了,第二段代码两次的输出都是2,而不是2和3。既然是共享同一个对象,为什么和上一段代码返回的结果不一样?两次add为什么没有累加?

很奇怪吧,两段代码我只是变了下变量,但结果却不一样,第一段代码的结果是大家可以预计的,那第二段代码为什么是这个结果呢?

原因是这样的,在Javascript中,一个对象继承自原型对象,则如果自己定义了和原型变量名字一样的变量,则会覆盖原型变量中的变量

在第二段代码中,当obj1执行add方法时,this.b++;等于this.b = this.b + 1;所以在obj1中生成了自己的b变量,并没有修改原型对象中的b变量。而在第一段代码中,调用的是arr数组对象的某个方法,修改的还是原来的数组对象。

这就是这段诡异代码的原因。深入了解JS的原型机制是非常重要的。

欢迎一同学习成长,新浪微博:弈轩-TB


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM