一、须要知识点回顾

根本类型(值类型)和援用类型

(根本类型)值类型:Number,Boolean,String,undefined,null

援用类型:object,Arrary

二、根本类型和援用类型复制的区别

值类型:对值类型的复制操作,仅仅是对值的进行一份拷贝,复制与被复制的会指向两份不同的数据。

援用类型:援用类型复制的是地址。所以最初会发现,复制与被复制的最终会指向同一份数据。

例子:

// 根本类型var a = 1;var b = a;a = 2;console.log(a, b); // 2, 1 ,a b指向不同的数据
// 援用类型指向同一份数据var a = {c: 1};var b = a;a.c = 2;console.log(a.c, b.c); // 2, 2 全是2,a b指向同一份数据

三、深拷贝和浅拷贝的区别

浅拷贝:只拷贝一层。
深拷贝:无限极拷贝。

四、深度拷贝的四个例子

办法一:
function clone(source){   if (!isObject(source)) return source;//参数校验更加优良     var target={};     for(var i in source){         if(source.hasOwnProperty(source){              if(typeof source[i] === 'object'){ // Object.prototype.toString.call(source[i] === '[Object Object]'                  target[i] = clone(source[i])              }else{                  target[i] = source[i];              }         }     return target;}function isObject(obj){   return Object.prototype.toString.call(obj === '[Object Object]'}
办法二:
function cloneJSON (source){ return JSON.parse(JSON.stringfy(source));}

办法三:

function cloneLoop(x) {    const root = {};    // 栈    const loopList = [        {            parent: root,            key: undefined,            data: x,        }    ];    while(loopList.length) {        // 深度优先        const node = loopList.pop();        const parent = node.parent;        const key = node.key;        const data = node.data;        // 初始化赋值指标,key为undefined则拷贝到父元素,否则拷贝到子元素        let res = parent;        if (typeof key !== 'undefined') {            res = parent[key] = {};        }        for(let k in data) {            if (data.hasOwnProperty(k)) {                if (typeof data[k] === 'object') {                    // 下一次循环                    loopList.push({                        parent: res,                        key: k,                        data: data[k],                    });                } else {                    res[k] = data[k];                }            }        }    }    return root;}
办法四:
// 放弃援用关系function cloneForce(x) {    // =============    const uniqueList = []; // 用来去重    // =============    let root = {}    // 循环数组    const loopList = [        {            parent: root,            key: undefined,            data: x,        }    ];    while(loopList.length) {        // 深度优先        const node = loopList.pop();        const parent = node.parent;        const key = node.key;        const data = node.data;        // 初始化赋值指标,key为undefined则拷贝到父元素,否则拷贝到子元素        let res = parent;        if (typeof key !== 'undefined') {            res = parent[key] = {};        }                // =============        // 数据曾经存在        let uniqueData = find(uniqueList, data);        if (uniqueData) {            parent[key] = uniqueData.target;            break; // 中断本次循环        }        // 数据不存在        // 保留源数据,在拷贝数据中对应的援用        uniqueList.push({            source: data,            target: res,        });        // =============            for(let k in data) {            if (data.hasOwnProperty(k)) {                if (typeof data[k] === 'object') {                    // 下一次循环                    loopList.push({                        parent: res,                        key: k,                        data: data[k],                    });                } else {                    res[k] = data[k];                }            }        }    }    return root;}function find(arr, item) {    for(let i = 0; i < arr.length; i++) {        if (arr[i].source === item) {            return arr[i];        }    }    return null;}

援用文章:https://segmentfault.com/a/11...