一篇文章帮你解决JS引用对象的指向问题

 

我们会在变量中存放对象,而引用类型的变量会存放内存地址。在这里会产生一系列出乎意料的结果,令人十分头疼。我也经过一番研究后才明白。

话不多说,先看以下代码:

题目1:

var user1 = {
    name: "u1",
    address: {
        country:"中国",
        city:"珠海"
    }
};
var user2 = {
    name: "u2",
    address: user1.address
};
user2.name = "666";
user2.address.city = "深圳";
console.log(user1.name,user2.name);
console.log(user1.address.city,user2.address.city)

到底会输出什么?纠结点在于以下两行代码有没有改变user1里的属性值。

user2.name = "666";
user2.address.city = "深圳";

解决思路

遇到这种情况,初学者最好的方法莫过于画图。我们一步一步来,先看user1的声明过程

var user1 = {
    name: "u1",
    address: {
        country:"中国",
        city:"珠海"
    }
};

在这一阶段,会创建一个user1的房间(内存空间),用于存放对象的内容,指向属性分别为name和address。同时address又是一个新的对象。图示如下:

OK!接下来往下看,下面的代码创建了一个user2对象,属性值仍然有两个,分别是name和address,但是不同的是,address并没有产生新的地址。也就是说,这两个address指向的地址一样!持有相同的引用。

var user2 = {
    name: "u2",
    address: user1.address
};

我们用图来表示,如下所示:

敲黑板!重点来了,我们对user2的属性值动手脚

user2.name = "666";
user2.address.city = "深圳";

非常明显,user2的name属性是属于他自己的,所以他修改了name,并不会影响到user1.name;与此同时,由于user2和user1指向同一个address对象,持有相同的引用,所以user2修改了address,user1也会受到影响。如下图所示:

分析完毕,我们到浏览器测试一下!!!结果和我们分析一致。

到这里不知道大家听懂了吗?画图能够很方便地理解这个问题。我们再来一道比较难的题目。

题目2:

var obj1 = {
    a: "123",
    b: "456",
    sub: {
        s1: "abc",
        s2: "bcd"
    }
};
var temp = obj1.sub;
var obj2 = obj1;
obj2.sub = {
    s1: "s",
    s2: "ddd"
};

console.log(obj1.sub.s1, obj2.sub.s1, temp.s1);
console.log(window);

这一道题,多了一个变量temp,但是原理和解题思路是一样的。如下图所示:

Step1: 定义了一个新的对象,开辟了内存空间用于存储对象的内容。

var obj1 = {
    a: "123",
    b: "456",
    sub: {
        s1: "abc",
        s2: "bcd"
    }
};

Step2: 定义了一个新的变量,赋值就是复制黏贴,这么理解的话,相当于又复制了一份sub,temp指向他

var temp = obj1.sub;

Step3: 定义了一个新的变量obj2,赋值就是复制黏贴,这么理解的话,相当于又复制了一份obj1,其余不变。

var obj2 = obj1;

Step4: 做到这里,我们发现离真相已经不远了,在接下来的代码,obj2修改sub里的属性值,就相当于obj1的sub也会改变。

obj2.sub = {
    s1: "s",
    s2: "ddd"
};

修改完如下图所示:

浏览器测试,结果如我们预料,这一修改并没有影响到temp的属性值,所以输出如下:

 

小贴士:

  • 出现“=”就是赋值,把右边的赋值给左边,相当于复制了一个一摸一样的,左边的变量指向的地址和右边的变量一样,持有相同的引用

  • 出现{}我们就可以判断一个新的对象产生,内存用来存储对象中的内容

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值