两道关于面向对象的面试题

 1 <script>
 2     var fun1 = function(){
 3         this.name = 'peter';
 4         return {
 5             name: 'jack'
 6         };
 7     }
 8     var p1 = new fun1();
 9     console.log(p1.name)//jack
10     
11     var fun2 = function(){
12         this.name = 'peter';
13         return 'jack';
14     }
15     var p2 = new fun2();
16     console.log(p2.name)//peter
17 </script>
 1 <script>
 2     var fun = function(){}
 3     fun.prototype = {
 4         info : {
 5             name : 'peter',
 6             age : 25
 7         }
 8     }
 9 
10     var a = new fun();
11     var b = new fun();
12     a.info.name = 'jack';
13     b.info.name = 'tom';
14     console.log(a.info.name)//tom
15     console.log(b.info.name)//tom
16 </script>
1 var a = {"x": 1};
2 var b = a;
3 a.x = 2;
4 b.x; //2
5 
6 a = {"x":3};
7 b.x;//2
8 a.x = 4;
9 b.x;//2

首先定义一个对象a,有一个属性x,值为1。接着让b = a,这一步的结果就是a和b指向了同一个对象。

 

在内存中,对象的存储和基本数据类型不同。基本数据类型直接保存在栈里,a = 1,b = 1,在栈里会保存两份1,分别赋值给a和b。修改a或b,对另一个变量不会有什么影响。

对象则不然,变量a和b如果被赋值对象,a和b实际上保存的只是对象的地址,而且a和b还是被存储在栈里,同时a和b的地址是相同的。但对象是在堆里保存,且只保存一份,对象的地址就是a和b的值,a和b都指向同一个对象。这与C里面的指针类似,修改指向同一个对象的任何一个变量,与之引用同一对象变量很快就会发生同样的变化。如下图:

所以现在的情况就是,a和b都指向了堆中的一个对象,这个对象的属性x值是1。那么a.x = 1,b.x自然也等于1。

1

a.x = 2

接下来发生一件事情,a修改了对象的x属性为2,这个变化反映到了堆中:

看,a和b还是指向了同一个对象,只不过对象中的x属性值变成了2。这一变化b很快就发现了,所以你再去访问b.x,实际上就是访问堆中的对象的x属性,也就是2。

1

a = {"x":3};

再后来,为a赋值了一个新的对象,虽然它也有一个属性x,但它确实是一个新对象!那么内存堆中发生了什么呢?首先,堆中原有的对象(x = 2的那个)还在那里。因为新建了一个对象(x = 3的),堆中就会出现一个新的对象,与原来的对象毫无关系。同时,b并没有变化,它还指向原有的对象(x = 2),但a指向原来的对象的地址却发生了变化,它指向了x = 3的这个新对象。

a的地址变了,同时a和原来的对象也没有指向关系了,它指向了新的对象,这个新对象的x = 3。而b对象没有任何变化,它还坚守着自己的对象,对象的x属性是2。

1

a.x = 4;

 
posted @ 2017-12-05 15:13  前端极客  阅读(1738)  评论(0编辑  收藏  举报