你不知道的简单数组拷贝方法全解

在我们的日常工作中,经常会遇到一些把一个值赋给另一个值,简单数据类型我们可以直接用=的方式进行简单值拷贝,那么遇到数组或者对象这些引用类型的拷贝应该怎么做呢?接下来简单总结了一些数组的浅拷贝和深拷贝的方法

浅拷贝【Shallow copy】
concat()

concat()方法主要用于数组的连接,该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

var arr1 = [1,2,3,4];
var arr10 = arr1.concat([]);
console.log(arr1); //1,2,3,4
console.log(arr10); //1,2,3,4
arr10.push(10);
console.log(arr10); //1,2,3,4,10
console.log(arr1); //1,2,3,4
//从此方法可以看出,使用concat方法实现了数组的浅拷贝,当操作arr10时没有影响到arr1数组的数据

slice()

slice()方法用于数组的切割,基本的语法是slice(start,end);start指定从原始数组的那个位置开始切割,end表示到那个位置结束【省略该参数默认结束位置是数组的最后一个原始】,我们可以使用slice()方法不指定任何参数实现数组的浅拷贝

var arr1 = [1,2,3];
var arr2 = arr1.slice();
console.log(arr1); //1,2,3
console.log(arr2); //1,2,3
arr2.push(4);
console.log(arr1); //1,2,3
console.log(arr2); // 1,2,3,4
//只影响了arr2数组,实现了数组的浅拷贝
...【ES6扩展运算符】

对ES6熟悉的人肯定都知道这个方法,...是ES6的新语法,它可以用于数组的扩展,

var arr1 = [1,2,3]
var arr2 = [...arr1];
console.log(arr1); //1,2,3
console.log(arr2); //1,2,3
arr2.push(4);
console.log(arr1); //1,2,3
console.log(arr2); // 1,2,3,4
//只影响了arr2数组,实现了数组的浅拷贝

以上是小编简单总结的数组的浅拷贝方法,同样你也可以用自己编写的方式进行数组浅拷贝

//实现浅拷贝
function shallowCopy( target ){
 if(typeof target !== 'object') return ;
 //判断目标类型,来创建返回值
 var newObj = target instanceof Array ? [] : {};
 
 for(var item in target){
  //只复制元素自身的属性,不复制原型链上的
  if(target.hasOwnProperty(item)){
   newObj[item] = target[item]
  }
 }
 
 return newObj
}
var test = [10,3,{name:'zs',age:10}]
var cloneTet = shallowCopy(test);
cloneTest[2].name = 'lisi';
console.log(test[2].name) //lisi
console.log(cloneTest[2].name) // lisi
//。

从上面的结果可以看出,在修改拷贝出来的cloneTest时,原始的test值也被修改了。为了实现不被修改,我们需要使用到深拷贝

深拷贝
巧用JSON.parse(JSON.stringify(Obj))

同样我们可以先将数组转为对象字符串然后在转为对象的方式进行浅拷贝

var arr1 = [1,2,3];
var arr2 = JSON.parse(JSON.stringify(arr1));
console.log(arr1); //1,2,3
console.log(arr2); //1,2,3
arr2.push(4);
console.log(arr1); //1,2,3
console.log(arr2); // 1,2,3,4
//只影响了arr2数组,实现了数组的浅拷贝
使用递归的方式实现深拷贝
var arr =[{name:'yf',students:{name:'zs',age:10,course:{name:'english'}}}]
var deepCopy = function(o) {
    if (o instanceof Array) {
        var n = [];
        for (var i = 0; i < o.length;   i) {
            n[i] = deepCopy(o[i]);
        }
        return n;

    } else if (o instanceof Object) {
        var n = {}
        for (var i in o) {
            n[i] = deepCopy(o[i]);
        }
        return n;
    } else {
        return o;
    }
}
var cloneArr = deepCopy(arr);
cloneArr[0].students.course.name ='aaaaaaaaaaaa';
console.log(cloneArr);
console.log(arr);

Note:此处的判断,一定要将 o instanceof Array放在o instanceof Object前边,为什么呢?英文数组进行instanceof Object的判断结果也是true,这就关系到原型链的问题了哈。

简单讲一下instanceof 的原理

function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
 var O = R.prototype;// 取 R 的显示原型
 L = L.__proto__;// 取 L 的隐式原型
 while (true) { 
   if (L === null)  //表示已经取到了原型链的最顶端
     return false; 
   if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true 
     return true; 
   L = L.__proto__; 
 } 
}

详解一下 [] instanceof Object的比较过程

//而上面说的 [] instanceof Object 返回结果为true
var arr = [1,2,3];
arr instanceof Object 
//首先取出arr.__proto__ = Array.prototype, 
arr.__proto__ === Object.prototype //第一轮比较返回false 
arr.__proto__.__proto__ === Object.prototype //第二轮比较返回true
等于
Array.prototype.__proto__ === Object.prototype //返回true

为什么会相等,可以深入学习一下原型链。小编下一篇会出相关详解


更多专业前端知识,请上 【猿2048】www.mk2048.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值