js里关于浅拷贝的问题。

今天看着这么一段 代码 讲浅拷贝

/* ================ 浅拷贝 ================ */
function simpleClone(initalObj) {
    var obj = {};
    for ( var i in initalObj) {
        obj[i] = initalObj[i];
    }
    return obj;
}

/* ================ 客户端调用 ================ */
var obj = {
    a: "hello",
    b: {
        a: "world",
        b: 21
    },
    c: ["Bob", "Tom", "Jenny"],
    d: function() {
        alert("hello world");
    }
}
var cloneObj = simpleClone(obj); // 对象拷贝

console.log(cloneObj.b); // {a: "world", b: 21}
console.log(cloneObj.c); // ["Bob", "Tom", "Jenny"]
console.log(cloneObj.d); // function() { alert("hello world"); }

// 修改拷贝后的对象
cloneObj.b.a = "changed";
cloneObj.c = [1, 2, 3];
cloneObj.d = function() { alert("changed"); };

console.log(obj.b); // {a: "changed", b: 21} // // 原对象所引用的对象被修改了

console.log(obj.c); // ["Bob", "Tom", "Jenny"] // 原对象所引用的对象未被修改
console.log(obj.d); // function() { alert("hello world"); } // 原对象所引用的函数未被修改

1、按道理讲 浅拷贝 不是应该仅仅复制对象的引用,而不是对象本身,那么 obj.c和obj.d都应该被修改了呀?

2、var cloneObj=obj ,算不算浅拷贝,怎么理解?

阅读 2.4k
3 个回答
var cloneObj=obj // 这才是浅拷贝,改变这里会联动改变
// 这个方法不是浅拷贝,是一级深拷贝,二级拷贝是浅拷贝,因为obj[i] = initalObj[i];就相当于你的var cloneObj=obj 。
function simpleClone(initalObj) {
    var obj = {};
    for ( var i in initalObj) {
        obj[i] = initalObj[i]; ////////注意这里  除非你递归赋值
    }
    return obj;
}

所以

cloneObj.a = "changed"; // obj不变
cloneObj.b.a = "changed"; // obj改变
  1. 存放对象的变量可以简单的理解为一个地址,通过这个地址再去获取其他子元素。2. 对象的浅拷贝指的是新建一个对象,把他的子元素的值依次复制过去。3. 因此拷贝后的对象虽然子元素值相同但是,做比较是不相等的,因为他们存放子元素变量的地址是不同的。4.你的第二种方式是地址的直接赋值,没有产生新的变量,或者说没有产生新的创建子元素的地址,这就不叫拷贝。

回头看自己的问题,自问自答吧:
  • 当时疑惑为什么obj.c没有改变,因为cloneObj.c重新指向一个新的地址值是[1,2,3],所以obj.c!=cloneObj.c。如果仅仅是 cloneObj.c.push('anything'),obj.c==cloneObj.c是成立的。
  • 我问的这个问题真的很蠢。‘=’就是复制的运算,我理解深浅复制是一套复制规则、逻辑,单单这么问很没有意义。当然 var cloneObj=obj ,算!
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题