拷贝

浅拷贝

原生方式

1. Object.assign 方法

let a = {
    hello: {
        world: 1
    }
};
let b = Object.assign({}, a);
a.hello.world = 2;
console.log(b.hello.world);     // 2

2. 扩展运算符(...)

let a = {
    hello: {
        world: 1
    }
};
let b = {...a};
a.hello.world = 2;
console.log(b.hello.world);     // 2

3. 数组 slice 方法

let a = [{hello: 'world'}, 1, 2];

b = a.slice(0, 1);
b[0].hello = '***';
a[0].hello;                     // '***'

4. 数组 concat 方法

let a = [{hello: 'world'}];
let b = [].concat(a);

b[0].hello = '***';
a[0].hello;                     // '***'

模拟实现

1. 原生实现

function shallowCopy(obj) {
    var result = obj.constructor === Array ? [] : {};
    for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
            result[i] = obj[i]
        }
    }
    return result;
}

2. 模拟 assign 方法

function assign (...args) {
    let first = args.shift();

    args.forEach(function(val) {
        for (let i in val) {
            if (val.hasOwnProperty(i)) {
                first[i] = val[i]
            }
        }
    });

    return first;
}

深拷贝

原生方式

1. JSON.parse(JSON.stringigy()) 方式

let a = {
    hello: {
        world: 1
    }
};
let b = JSON.parse(JSON.stringify(a));
b.hello.world = 2;
a.hello.world;                  // 1

缺点:

  • 时间对象(new Date),将会变成时间字符串的形式。
  • RegExp、Error对象将会被转成空对象({})。
  • undefined 和 function() {} 会导致改键值被忽略。
  • NaN、Infinity和-Infinity会被转化为null。
  • 只能序列化对象的可枚举的自有属性。
  • 不能解决循环引用的对象。

注: 以上格式变化是在 JSON.stringify 就已经被改了。

模拟实现

1. 原生 js 方式

兼容 JSON 方式。

function deepCopy(obj){
    var str,
        result = obj.constructor === Array ? [] : {};

    if (window.JSON){
        str = JSON.stringify(obj),
        result = JSON.parse(str); 
    } else {
        for (var i in obj){
            result [i] = typeof obj[i] === 'object' ? deepCopy(obj[i]) : obj[i]; 
        }
    }
    return result ;
};

4. 模拟 assign 的方式实现深拷贝

function assign (...args) {
    let first = args.shift();

    args.forEach(function(val) {
        deepCopy(first, val);
    });

    return first;
}

function deepCopy(target, other) {
    if (!target) {
        target = other.constructor === Array ? [] : {};
    }
    for (let i in other) {
        target[i] = typeof other[i] === 'object' ? deepCopy(target[i], other[i]) : other[i]
    }

    return target;
}

其他

jQ

Copyright & copy https://www.zhuyuntao.cn 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-11-03 12:36:28

results matching ""

    No results matching ""