浅拷贝和深拷贝
数组偏平化(拉平)
js
// 第一种方式 使用递归函数遍历旧数组
function flatArray(arr) {
// 创建新的空数组
let newArr = [];
// 使用循环结构遍历 arr
for (var i = 0; i < arr.length; i ++) {
// 判断当前的元素是否是数组
if (arr[i] instanceof Array) {
// 递归调用
newArr = newArr.concat(flatArray(arr[i]));
} else {
// 将该元素添加到新数组中
newArr.push(arr[i]);
}
}
// 返回新数组
return newArr;
}
// 第二种方式 缺点是里面的元素都会转为字符串
nums.join().split(',');
// 第三种方式 数组的flat方法
nums.flat(Infinity);
对象的浅拷贝
数组的浅拷贝:
仅仅拷贝了对象的外表解构(一维),数组内嵌套的数据(地址)没有变化。
js
1. [...arr] 扩展运算符
2. arr.concat() 返回新的数组 ,参数是空表示自己
3. arr.slice() 返回新的数组,从头截取到尾
4. Array.from(arr) 返回新的数组,将可遍历对象转为纯数组。
对象的浅拷贝:
仅仅拷贝了对象的外表解构(一维),对象内嵌套的数据(地址)没有变化。
js
1. {...obj} 扩展运算符
2. Object.assign({}, obj) 返回新对象,利用对象合并实现对象浅拷贝
JSON对象的拷贝
js
JSON.stringify() 将对象或数组转为json格式的字符串。参数是对象。
JSON.parse() 将json格式的字符串 恢复成对象或数组,参数是json格式的字符串。
对象的深拷贝
借助于JSON
js
// 1. 借助于JSON 无法拷贝方法,适合于纯数据对象,没有方法的对象叫做纯数据对象。
JSON.parse(JSON.stringify(obj));
借助于递归函数
js
/**
* 判断数据的类型
* @params 要判断类型的数据
* @returns string 数据的类型
判断数据类型
Object.prototype.toString是顶层原型上的方法。返回值是 Object Object,是为了给Object的实例准备的
通过指定Object this的指向那种数据类型,他的返回结果就是谁的类型,这是ES6的本身设计。
*/
function getType(data) {
const typeStr = Object.prototype.toString.call(data);
return typeStr.slice(8, typeStr.length-1);
};
/**
* 实现对象和数组的深拷贝
* @params 要拷贝的数据
* @returns 拷贝好的数据
*/
function deepClone(obj) {
// 判断 obj 是 Object 类型还是 Array 类型
let res;
if (getType(obj) === 'Object') {
res = {};
} else if (getType(obj) === 'Array') {
res = [];
} else {
return obj;
}
// 遍历 Object数据或者Array数据
for (let i in obj) {
// 将obj中中的成员添加到 res
res[i] = deepClone(obj[i]);
}
// 返回res
return res;
}