We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
深浅拷贝实际上针对的是复杂数据类型而言的,浅拷贝只复制对象的一层属性,深拷贝则复制了所有层级的属性。因为Js存储对象是存地址的,所以浅拷贝会导致obj1和obj2指向同一块内存地址,而深拷贝则是为对象开辟一块新的内存,复制对象进来,因此对于深拷贝而言,obj1和obj2的操作互不影响。
指的是将一个对象的属性值复制到另外一个对象,如果有的属性的值为引用类型的话,那么会将这个引用的地址复制给对象,因此两个对象会有同一个引用类型的引用。浅拷贝可以使用Object.assign()和展开运算符来实现(如:const {a, b, c} = {1, 2, {3, 4}}; 所以c = {3, 4})。 如何实现一个对象或者数组的浅拷贝。 想一想,好像很简单,遍历对象,然后把属性和属性值都放在一个新的对象就好了~
function shallowCopy(object) { // 只拷贝对象 if (!object || typeof object !== "object") { return; } // 根据object的类型判断是新建一个数组还是对象 let newObject = Array.isArray(object) ? [] : {}; // 遍历object,并且判断是object的属性才拷贝 for (let key in object) { if (object.hasOwnProperty(key)) { newObject[key] = object[key]; } } return newObject; }
相对于浅拷贝而言,如果遇到属性值为引用类型的时候,它新建一个引用类型并将对应的值复制给它,因此对象获得的一个新的引用类型而不是一个原有类型的引用。深拷贝对于一些对象可以使用JSON的两个函数来实现,但是由于JSON的对象格式化比js的对象格式化更加严格,所以如果属性值里面出现函数或者Symbol类型的值时,会转换失败。 那如何实现一个深拷贝呢?说起来也简单,我们在拷贝的时候判断一下属性值的类型,如果是对象,我们递归调用深拷贝函数不就好了~
function deepCopy(object) { if (!object || typeof object !== "object") return; let newObject = Array.isArray(object) ? [] : {}; for (let key in object) { if (object.hasOwnProperty(key)) { newObject[key] = typeof object[key] === "object" ? deepCopy(object[key]) : object[key]; } } return newObject; }
//例1 var source = { name:"source", child:{ name:"child" } } var target = JSON.parse(JSON.stringify(source)); target.name = "target"; //改变target的name属性 console.log(source.name); //source console.log(target.name); //target target.child.name = "target child"; //改变target的child console.log(source.child.name); //child console.log(target.child.name); //target child //例2 var source = { name:function(){console.log(1);}, child:{ name:"child" } } var target = JSON.parse(JSON.stringify(source)); console.log(target.name); //undefined //例3 var source = { name:function(){console.log(1);}, child:new RegExp("e") } var target = JSON.parse(JSON.stringify(source)); console.log(target.name); //undefined console.log(target.child); //Object {}
这种方法使用较为简单,可以满足基本的深拷贝需求,而且能够处理JSON格式能表示的所有数据类型,但是对于正则表达式类型、函数类型等无法进行深拷贝(而且会直接丢失相应的值)。 还有一点不好的地方是它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。同时如果对象中存在循环引用的情况也无法正确处理。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
参考文章
前言
深浅拷贝实际上针对的是复杂数据类型而言的,浅拷贝只复制对象的一层属性,深拷贝则复制了所有层级的属性。因为Js存储对象是存地址的,所以浅拷贝会导致obj1和obj2指向同一块内存地址,而深拷贝则是为对象开辟一块新的内存,复制对象进来,因此对于深拷贝而言,obj1和obj2的操作互不影响。
浅拷贝实现
指的是将一个对象的属性值复制到另外一个对象,如果有的属性的值为引用类型的话,那么会将这个引用的地址复制给对象,因此两个对象会有同一个引用类型的引用。浅拷贝可以使用Object.assign()和展开运算符来实现(如:const {a, b, c} = {1, 2, {3, 4}}; 所以c = {3, 4})。
如何实现一个对象或者数组的浅拷贝。
想一想,好像很简单,遍历对象,然后把属性和属性值都放在一个新的对象就好了~
深拷贝实现
相对于浅拷贝而言,如果遇到属性值为引用类型的时候,它新建一个引用类型并将对应的值复制给它,因此对象获得的一个新的引用类型而不是一个原有类型的引用。深拷贝对于一些对象可以使用JSON的两个函数来实现,但是由于JSON的对象格式化比js的对象格式化更加严格,所以如果属性值里面出现函数或者Symbol类型的值时,会转换失败。
那如何实现一个深拷贝呢?说起来也简单,我们在拷贝的时候判断一下属性值的类型,如果是对象,我们递归调用深拷贝函数不就好了~
思考
借助这两个方法,也可以实现对象的深拷贝。
示例
这种方法使用较为简单,可以满足基本的深拷贝需求,而且能够处理JSON格式能表示的所有数据类型,但是对于正则表达式类型、函数类型等无法进行深拷贝(而且会直接丢失相应的值)。
还有一点不好的地方是它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。同时如果对象中存在循环引用的情况也无法正确处理。
The text was updated successfully, but these errors were encountered: