浅拷贝:浅拷贝只是复制了内存地址,如果原地址中的对象改变了,浅拷贝出来的对象也会相应改变。

深拷贝:开辟了一块新的内存存放地址和地址指向的对象,原地址的任何对象改变了,深拷贝出来的对象不变。

浅拷贝数组(只拷贝第一级数组):

1.直接遍历

var arr = [1,2,3,4];

function copy(arg){

  var newArr = [];

  for(var i = 0; i < arr.length; i++) {
newArr.push(arr[i]);
} return newArr;
} var newArry = copy(arr);
console.log(newArry);
newArry[0] = 10;
console.log(newArry); // [10,2,3,4]
console.log(arr) // [1,2,3,4]

2.slice

var arr = [1,2,3,4]
var copyArr = arr.slice();
copyArr[0] = 10;
console.log(copyArr); // [10,2,3,4]
console.log(arr); // [1,2,3,4]

slice(start,end),slice()方法返回一个数组中复制出来的元素组成新数组,start指起始元素下标,end指终止元素下标

当slice()不带任何参数时,默认返回一个和原数组一样的新数组

3.concat()

var arr = [1,2,3,4]
var copyArr = arr.concat();
copyArr[0] = 10;
console.log(copyArr); // [10,2,3,4]
console.log(arr); // [1,2,3,4]

array.concat(array1,array2,.......,arrayN),concat()方法用于连接两个或多个数组(不会改变原数组,返回被连接数组的副本)

然而如果第一级数组元素是对象或数组,上面三种方式都失效:

var arr = [
{number:1},
{number:2},
{number:3} ]
var copyArr = arr.slice();
copyArr[0].number = 10;
console.log(copyArr); // [{number: 100}, { number: 2 },{ number: 3 }]
console.log(arr); // [{number: 100}, { number: 2 }, { number: 3 }]

浅拷贝对象(如果对象中的值不为数组或对象)

1.直接遍历

  var obj = {
name: "张三",
job: "学生"
} function copy (arg) {
let newobj = {}
for(let item in obj) {
newobj[item] = obj;
}
return newobj;
} var copyobj = copy(obj)
copyobj.name = "李四"
console.log(copyobj) // {name: '李四', job:: '学生'}
console.log(obj) // {name: '张三', job:: '学生'}

2.ES6的Object.assign

var obj = {
name: '张三',
job: '学生'
} var copyobj = Object.assign({},obj)
copyobj.name = '李四'
console.log(copyobj) // {name: '李四', job:: '学生'}
console.log(obj) // {name: '张三', job:: '学生'}

Object.assign:用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target),并返回合并后的target

用法: Object.assign(target, source1, source2); 所以 copyObj = Object.assign({}, obj); 这段代码将会把obj中的一级属性都拷贝到 {}中,然后将其返回赋给copyObj

3.ES6扩展运算符

var obj = {
name: '张三',
job: '学生'
} var copyobj = {...obj}
copyobj.name = '李四'
console.log(copyobj)
console.log(obj)

扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中

深拷贝

JSON.stringify()和JSON.parse

用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。

但是这种方法也有不少坏处,譬如它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。

这种方法能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,即那些能够被 json 直接表示的数据结构。RegExp对象是无法通过这种方式深拷贝。

也就是说,只有可以转成JSON格式的对象才可以这样用,像function、undefined、symbol、循环引用的对象没办法转成JSON。

var obj1 = { fun: function(){ console.log(123) } };
var obj2 = JSON.parse(JSON.stringify(obj1));
console.log(typeof obj1.fun);
// 'function'
console.log(typeof obj2.fun);
// 'undefined' <-- 没复制

使用递归函数实现一个深拷贝的方法

function deepClone(obj) {
let objClone = Array.isArray(obj) ? [] : {};
if(obj && typeof obj === "object") {
for(key in obj) {
if(obj.hasOwnProperty(key)) {
if(obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone
}

JS JavaScript深拷贝、浅拷贝的更多相关文章

  1. 一篇文章彻底说清JS的深拷贝/浅拷贝

    一篇文章彻底说清JS的深拷贝and浅拷贝 这篇文章的受众 第一类,业务需要,急需知道如何深拷贝JS对象的开发者. 第二类,希望扎实JS基础,将来好去面试官前秀操作的好学者. 写给第一类读者 你只需要一 ...

  2. 关于JavaScript的浅拷贝和深拷贝

    在 JS 中有一些基本类型像是Number.String.Boolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他 ...

  3. javascript篇-浅拷贝与深拷贝

    理解javascript 的浅拷贝与深拷贝,首先看一下js的数据类型: js有5种基本数据类型:undefined,null,boolean,number,string 还有一种复杂的数据类型(也叫引 ...

  4. 全面聊聊JavaScript的浅拷贝和深拷贝

    一.背景      首先我们可以看下面这段简单的代码: var obj = {name:'程序猿',sex:'男'}; var arr = ['程序猿','程序媛']; var copyobj = o ...

  5. JS Object Deep Copy & 深拷贝 & 浅拷贝

    JS Object Deep Copy & 深拷贝 & 浅拷贝 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Refe ...

  6. javaScript深拷贝和浅拷贝简单梳理

    在了解深拷贝和浅拷贝之前,我们先梳理一下: JavaScript中,分为基本数据类型(原始值)和复杂类型(对象),同时它们各自的数据类型细分下又有好几种数据类型 基本数据类型 数字Number 字符串 ...

  7. 深拷贝/浅拷贝之Js / AngularJs

    var a = [1,2,3,4]; var b = a; b[1] = 8; console.log("a:" + a );//1,8,3,4 consloe.log(" ...

  8. JavaScript之深拷贝&浅拷贝

    深拷贝&浅拷贝,说起来都明白,但是说不出所以然.今天就系统的整理下思绪,一点点的将其分析出所以然 废话不多说 浅拷贝 简单的说就是一个值引用,学生时代接触过编程的人都应该了解过指针,浅拷贝可以 ...

  9. javascript 深拷贝与浅拷贝

    javascript 深拷贝与浅拷贝 深拷贝与浅拷贝 赋值和深/浅拷贝的区别 浅拷贝的实现方式 1.Object.assign() 2.函数库lodash的_.clone方法 3.展开运算符... 4 ...

随机推荐

  1. HDU 1069—— Monkey and Banana——————【dp】

    Monkey and Banana Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  2. 什么是PV,什么是UV,什么是IP. 流量统计的各种数据!

    pv流量 什么是PV? 解答:PV是指页面刷新的次数,每一次页面刷新,就算做一次pv流量. PV高一定代表来访者多吗? 解答:不一定如此,一般来说,PV与来访者的数量成正比,但是PV并不直接决定页面的 ...

  3. 正则表达式的实践demo

    正则表达式十分强大,几乎在所有框架中处处可以看到,下载框架源码仔细阅读肯定可以发现.在项目应用中也经常需要正则的帮助,举个栗子,我们常需要用到的表单验证输入....其实还有很多,不一一道出,在这里我搜 ...

  4. html页面的加载顺序

    页面加载顺序: 解析HTML结构加载外部脚本和样式表文件解析并执行脚本代码构造HTML DOM模型加载图片等外部文件页面加载完毕 window.onload = function () {  }  / ...

  5. vue.extend与vue.component的区别和联系

    一味的闷头开发,却对基础概念缺乏理解,是个大坑... 查阅官网后现对自己的理解记录一下,用于日后复习巩固 Vue.extend({}) 简述:使用vue.extend返回一个子类构造函数,也就是预设部 ...

  6. JavaScript数组求和

    <script> function demo(){ var d=document.getElementsByTagName("input")[0].value.spli ...

  7. 【2015 Week Task】

    2015 第17周 task:项目语音识别技术整理 2015 第18周 task:项目key技术整理

  8. Android 自定义圆形图表

    <com...SignChartView android:id="@+id/signChart" android:layout_width="265dp" ...

  9. 常见HTTP状态200,304,403,404,503

    下面提供 HTTP 状态码的完整列表.您也可以查看 W3C官方HTTP 状态码说明(英文). 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态码. 100(继续) 请求者应当继续提出请求 ...

  10. SQL Server ->> SET ANSI_PADDING对于字符串插入的影响

    前面写了<SQL Server ->> 字符串对比>讲了SQL Server在做字符串对比和排序时的对尾随空格的处理方法. 再说说有一个和字符串尾随空格相关联的东西就是SET ...