关于对象的存储、引用和比较,真的懂了么?

270 阅读2分钟

对象之间的比较,是引用地址的比较。标识符存放在栈内存中,标识符所指向的引用地址存放在堆内存中。两个标识符指向的是同一个内存地址,这两个对象才相等。

拥有共同引用地址的对象,当给自身添加属性时,同时也会“污染”其他具有共同引用关系的“小伙伴”。但是,如果给该对象重新赋值,则意味着它和其他“小伙伴”断绝关系,因为重新赋值意味着指针指向了另一个内存空间。

嗯,道理我都懂,但接下来这个例子呢,考考自己的小脑瓜~

<!--第一个-->
let obj = {};
let temp = obj;
for (let i = 0; i < 3; i++) {
    temp['data'] = {};
    temp = {};
}
console.log('obj', obj);

<!--第二个-->
let obj = {};
let temp = obj;
for (let i = 0; i < 3; i++) {
    temp = temp['data'] = {}; 
    // 上面这一句相当于下面两句
    // temp['data'] = {};
    // temp = temp['data'];
}
console.log('obj', obj);

有没有同学可以告诉我,为什么两个obj打印的结果不一样?

延伸:

<!--根据广度和深度创建data-->

function createData(deep, breadth) {
    var data = {};
    var temp = data;

    for (var i = 0; i < deep; i++) {
        temp = temp['data'] = {};
        for (var j = 0; j < breadth; j++) {
            temp[j] = j;
        }
    }
    return data;
}

cheat sheet:

第一个例子中的temp,在每一次循环中,都重新创造了一个新的、独立的对象。

第二个例子中的temp,相当于是一个指针,每一次循环指针都指向obj对象内部最新创造的对象,它并没有离开过最开始的引用地址,而是在原有的内存空间内部活动。换句话说,理解第二个例子链式赋值的关键,就在于理解中间的temp['data'],这个是在原有的对象中添加属性的意思。

你的看法是?欢迎讨论,期待~