前端面试题-js部分-浅拷贝与深拷贝

参考资料

https://juejin.im/post/59ac1c4ef265da248e75892b

看完上面的参考资料后你会发现, js有2大类型数据基础数据类型(boolean,undefined,null,string,number)及引用类型(object)

基本数据类型的值是不可变的,动态修改了基本数据类型的值,它的原始值也是不会改变的,例如:

var str = 'abc'
str[1] = 'f'; // f, 只是返回了一个新字符,
console.log(str); // abc,

参考资料中:复制代码这一点其实开始我是比较迷惑的,总是感觉 js 是一个灵活的语言,任何值应该都是可变的,真是图样图森破,我们通常情况下都是对一个变量重新赋值,而不是改变基本数据类型的值。就如上述引用所说的那样,在 js 中没有方法是可以改变布尔值和数字的。倒是有很多操作字符串的方法,但是这些方法都是返回一个新的字符串,并没有改变其原有的数据。

var p1 = {a: 1}
var p2 = {a: 2}
p1 === p2; // false,因为指向的堆栈内存地址不同不是同一个

var obj = {a: 1}
var p1 = obj;
var p2 = obj;
p1 === p2; // true,因为他们指向同一个内存地址
p1.b = 2;
console.log(p2.b); // 2 因为指向同一内存地址,所以p2也会受影响

综上所述,并不是真正的浅拷贝,只是引用而已,浅拷贝和"="赋值还是有区别的。

// 此处内容为参考资料的内容
// 浅拷贝与赋值的区别
    var obj1 = {
        'name' : 'zhangsan',
        'age' :  '18',
        'language' : [1,[2,3],[4,5]],
    };

    var obj2 = obj1;


    var obj3 = shallowCopy(obj1);
    function shallowCopy(src) {
        var dst = {};
        for (var prop in src) {
            if (src.hasOwnProperty(prop)) {
                dst[prop] = src[prop];
            }
        }
        return dst;
    }

    obj2.name = "lisi";
    obj3.age = "20";

    obj2.language[1] = ["二","三"];
    obj3.language[2] = ["四","五"];

    console.log(obj1);  
    //obj1 = {
    //    'name' : 'lisi',
    //    'age' :  '18',
    //    'language' : [1,["二","三"],["四","五"]],
    //};

    console.log(obj2);
    //obj2 = {
    //    'name' : 'lisi',
    //    'age' :  '18',
    //    'language' : [1,["二","三"],["四","五"]],
    //};

    console.log(obj3);
    //obj3 = {
    //    'name' : 'zhangsan',
    //    'age' :  '20',
    //    'language' : [1,["二","三"],["四","五"]],
    //};
  • obj1:原始数据
  • obj2:赋值操作得到
  • obj3:浅拷贝得到

建议还是看参考资料吧。实在是太详细太明白了。

总结下:

类型 和原数据是否指向同一对象 第一层数据为基本数据类型 原数据中包含子对象
赋值 改变会使原数据一同改变 改变会使原数据一同改变
浅拷贝 改变不会使原数据一同改变 改变会使原数据一同改变
深拷贝 改变不会使原数据一同改变 改变不会使原数据一同改变

我们在写代码的时候遇到的困难多是如何写出深拷贝,及复制一个对象,对该对象修改不会影响原始对象,最简单的方法就是: var newObj = JSON.parse(JSON.stringify(obj))

你可能感兴趣的:(前端面试题-js部分-浅拷贝与深拷贝)