回答

收藏

Javascript深浅拷贝

前端知识 前端知识 848 人阅读 | 0 人回复 | 2024-08-31

本帖最后由 wangyang 于 2024-8-31 17:34 编辑

Javascript有六种基本数据类型(也就是简单数据类型),它们分别是:Undefined,Null,Boolean,Symbol,Number和String。还含有一种复杂数据类型,就是对象
注意Undefined和Null的区别,Undefined类型只有一个值,就是undefined,Null类型也只有一个值,也就是null
Undefined其实就是已声明未赋值的变量输出的结果
null其实就是一个不存在的对象的结果
  1. var c;
  2. console.log(c)//undefined

  3. console.log(document.getElementById('wsscat'))//没有id为wsscat的节点,输出null
复制代码
简单的数据类型和复杂的数据类型有以下重要的区别
对于简单数据类型
它们值在占据了内存中固定大小的空间,并被保存在栈内存中。当一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本,还有就是不能给基本数据类型的值添加属性
  1. var a = 1;
  2. var b = a;
  3. a.attr = 'wsscat';
  4. console.log(a.attr)//undefined
复制代码
上面代码中a就是简单数据类型(Number),b就是a的副本,它们两者都占有不同位置但相等的内存空间
对于复杂的数据类型
复杂的数据类型即引用类型,它的值是对象,保存在堆内存中,包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针。从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象。
  1. var obj = {
  2.     name:'wsscat',
  3.     age:0
  4. }
  5. var obj2 = obj;
  6. obj2['c'] = 5;
  7. console.log(obj);//Object {name: "wsscat", age: 0, c: 5}
复制代码
我们可以看到obj赋值给obj2后,当我们更改其中一个对象的属性值,两个对象都发生了改变,究其原因局势因为obj和obj2这两个变量都指向同一个指针,赋值只是复制了指针,所以当我们改变其中一个的值就会影响另外一个变量的值
浅拷贝
其实这段代码就是浅拷贝,有时候我们只是想备份数组,但是只是简单让它赋给一个变量,改变其中一个,另外一个就紧跟着改变,但很多时候这不是我们想要的
  1. var obj = {
  2.     name:'wsscat',
  3.     age:0
  4. }
  5. var obj2 = obj;
  6. obj2['c'] = 5;
  7. console.log(obj);//Object {name: "wsscat", age: 0, c: 5}
  8. console.log(obj2);////Object {name: "wsscat", age: 0, c: 5}
复制代码
深拷贝
数组
对于数组我们可以使用slice()和concat()方法来解决上面的问题
slice
  1. var arr = ['wsscat', 'autumns', 'winds'];
  2. var arrCopy = arr.slice(0);
  3. arrCopy[0] = 'tacssw'
  4. console.log(arr)//['wsscat', 'autumns', 'winds']
  5. console.log(arrCopy)//['tacssw', 'autumns', 'winds']
复制代码
concat
  1. var arr = ['wsscat', 'autumns', 'winds'];
  2. var arrCopy = arr.concat();
  3. arrCopy[0] = 'tacssw'
  4. console.log(arr)//['wsscat', 'autumns', 'winds']
  5. console.log(arrCopy)//['tacssw', 'autumns', 'winds']
复制代码
对象
对象我们可以定义一个新的对象并遍历新的属性上去实现深拷贝
  1. var obj = {
  2.     name:'wsscat',
  3.     age:0
  4. }

  5. var obj2 = new Object();
  6. obj2.name = obj.name;
  7. obj2.age = obj.age

  8. obj.name = 'autumns';
  9. console.log(obj);//Object {name: "autumns", age: 0}
  10. console.log(obj2);//Object {name: "wsscat", age: 0}
复制代码
当然我们可以封装好一个方法来处理对象的深拷贝,代码如下
  1. var obj = {
  2.     name: 'wsscat',
  3.     age: 0
  4. }
  5. var deepCopy = function(source) {
  6.     var result = {};
  7.     for(var key in source) {
  8.         if(typeof source[key] === 'object') {
  9.             result[key] = deepCopy(source[key])
  10.         } else {
  11.             result[key] = source[key]
  12.         }
  13.     }
  14.     return result;
  15. }
  16. var obj3 = deepCopy(obj)
  17. obj.name = 'autumns';
  18. console.log(obj);//Object {name: "autumns", age: 0}
  19. console.log(obj3);//Object {name: "wsscat", age: 0}
复制代码


分享到:
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

58 积分
16 主题
+ 关注