由之前章节可以得到的几种结论再深入了解
之前章节
前一期也简单的讲了一下克隆对象,
这个确实挺费劲的。
我们再重新了解一下JavaScript的类型
在 js
中一切实例皆是对象,具体分为 原始类型 和 合成类型 :
原始类型 对象指的是 Undefined
、 Null
、Boolean
、Number
和 String
,按值传递。
合成类型 对象指的是 array
、 object
以及 function
,按址传递,传递的时候是内存中的地址。
克隆或者拷贝分为2种: 浅度克隆 、 深度克隆 。
浅度克隆 :基本类型为值传递,对象仍为引用传递。
深度克隆 :所有元素或属性均完全克隆,并于原引用类型完全独立,即,在后面修改对象的属性的时候,原对象不会被修改。
又或许你刚听说“深度克隆”这个词,简单来说,就是说有个变量a,a的值是个对象(包括基本数据类型),现在你要创建一个变量b,使得它拥有跟a一样的方法和属性等等。但是a和b之间不能相互影响,即a的值的改变不影响b值的变化。直接赋值可好?
定义被克隆的对象
let obj1 = {
name: "dwp1",
age: 18,
zero: 0,
boo: false,
boo2: true,
n: null,
N: NaN,
un: undefined,
run: function () {
console.log(this.name + "---run");
},
objChild: {
name: "objChild-dwp1",
age: 18,
zero: 0,
boo: false,
boo2: true,
n: null,
N: NaN,
un: undefined,
run: function () {
console.log(this.name + "objChild----run");
},
},
};
obj1.run();
通过转字符串的方式来达到克隆的目的
/**
* 转字符串的克隆方式 不能克隆函数
* 无法克隆 函数, undefined 的key value
* NaN 会被转为null
* */
let obj2 = JSON.parse(JSON.stringify(obj1));
console.dir(obj1);
console.dir(obj2);
// 结论
// 转字符串的克隆方式 不能克隆函数,undefined
通过扩展运算符达到克隆的目的
/**
* 这种方式看起来没啥问题
*
* 由上期我们这里测试和上期我们得到的结论一样,这这方式得到的对象是不完全克隆的,、
* 坑比较多。 `伪克隆`
*
*/
let obj3 = { ...obj1 };
console.dir(obj1);
obj3.name = "dwpnb";
obj3.run();
// obj3.objChild.name = "dwpnb-chil"
console.dir(obj3);
// 例子:
let obj = {name: 'obj1', dwp: {chi: 'dwp cih'}};
// let obj = {name: 'obj1', dwp:'dwp1'};
// let obj = {name: 'obj1', dwp:'dwp1'};
let cyObj1 = {...obj};
cyObj1.name = 'cyObj1';
cyObj1.dwp.chi = 'dwp.chi'; // 注意这个时候 得到的是一个对象地址
console.log(cyObj1);
let cyObj2 = JSON.parse(JSON.stringify(obj));
cyObj2.name = 'cyObj2';
console.log(cyObj2);
console.log('obj', obj);
结论:
- 一维数据结构的深拷贝方法建议使用:Object.assign();
- 二维数据结构及以上的深拷贝方法建议使用:JSON.parse(JSON.stringify());
- 特别复杂的数据结构的深拷贝方法建议使用:Loadsh.cloneDeep();
- 一般特别复杂的对象会内置克隆方法
贝方法建议使用:JSON.parse(JSON.stringify());
3. 特别复杂的数据结构的深拷贝方法建议使用:Loadsh.cloneDeep();
4. 一般特别复杂的对象会内置克隆方法
欢迎关注留言加评论, 谢谢!