关于一道面试题

 1 var foo,bar1,bar2;
 2 function Foo(){
 3     this.counter={i:0};
 4     this.counter2=0;
 5 }
 6 function Bar(){};
 7 foo=new Foo();
 8 Bar.prototype=foo;
 9 Bar.prototype.sayHello=function(){
10     console.log(this.counter.i,this.counter2);
11     this.counter.i+=1;
12     this.counter2+=1;
13 }
14 var bar1=new Bar();
15 var bar2=new Bar();
16 foo.sayHello();
17 bar1.sayHello();
18 bar2.sayHello();
19 foo.sayHello();
 1 一眼瞟过,大概的意思是:
 2 
 3 声明了3个变量:foo,bar1,bar2; 
 4 
 5 接着声明了2个构造函数:Foo,Bar; 
 6 
 7 接着构造函数Foo的实例对象(new Foo)赋值给foo这个变量,
 8 
 9 接着foo这个变量又赋值给构造函数Bar的原型,即Bar.prototype; 
10 
11 接着在构造函数Bar的原型上添加了一个sayHello的方法;
12 
13 接着构造函数Bar的实例对象赋值给变量bar1
14 
15 接着构造函数Bar的实例对象赋值给变量bar2
16 
17 接着执行foo.sayHello();
18 
19 接着执行bar1.sayHello();
20 
21 接着执行bar2.sayHello();
22 
23 接着执行foo.sayHello();
1 //其中bar.prototype = foo就是对象引用  同时bar也继承了foo的所有属性和方法
2 
3 Bar.prototype.counter2=10;//修改Bar原型上的属性 counter2 =10;原本是 0;
4 
5 console.log(foo.counter2);//Foo的实例对象foo下面的counter2 却跟着同时 变成10了

第一个foo.sayHello()执行的结果:

执行第一个foo.sayHello()的时候,因为console.log(this.counter.i,this.counter2)在 this.counter.i+=1;this.counter2+=1;前面,用的值自然就是初始值this.counter={i:0};this.counter2=0;
第一个foo.sayHello()执行的结果就是 0 0

bar1.sayHello()执行的结果:

执行bar1.sayHello()时,由于已经执行过foo.sayHello(),引用地址中的变成 this.counter={i:1}; this.counter2=1;因此执行结果就是 1,1

bar2.sayHello()执行的结果:

执行bar2.sayHello()时,由于已经执行过foo.sayHello()由于是bar2又是一个实例化对象,由于每次实例化时,构造函数里的基本数据类型也会被初始化(this.counter2=0),复合数据this.counter不会被初始化({i:2});因此执行bar2.sayHello()的结果:2 1

第二个foo.sayHello()执行的结果:

执行第一个foo.sayHello()后,foo实例下的属性已经变成this.counter={i:1} this.counter2=1,经过bar1.sayHello()和bar2.sayHello()的执行,改变了只是复合属性this.counter的i值,而this.counter2是基本数据类型,不会影响到,因此,执行第二个foo.sayHello(),由于this.counter={i:3} this.counter2=1,结果就是 3 1

猜你喜欢

转载自www.cnblogs.com/studyshufei/p/9053012.html