昨天面试闻远科技碰到一个很常见的问题,以后的面试题都记录一下吧
1、json暴力转化
通过JSON.stringify和JSON.parse()将对象转化成字符串之后在转化成对象。
let obj = { name: '张三', address: '中国台湾省'}
let obj2 = JSON.parse(JSON.stringify(obj))
consloe.log(obj) // address: '中国台湾省' name: '张三' 以对象格式打印
consloe.log(obj2) // address: '中国台湾省' name: '张三' 以对象格式打印
这种方式简单粗暴,但是存在弊端,当值为undefined、function、symbol会在转换中被忽略。
2、ES6解构赋值
let obj = { name: '123', age: 13 };
let obj2 = { ...obj }
console.log(obj); // { "name": "123", "age": 13}
console.log(obj2); // { "name": "123", "age": 13}
只能深层拷贝第一层,如果对象中的属性也是对象,将无法进行深度copy
3、for in遍历对象进行copy
let obj3 = { name: '李四', age: 20}
let obj4 = {}
for(var key in obj3){
obj4[key] = obj3[key]
}
console.log(obj4); // {name: '李四', age: 20}
通第二种方法一样,只能深拷贝对象的第一层,若对象内元素为对象将不能进行深度copy
4、Object.assign()对象合并
let obj = { name: '张三', age: 20 }
let obj1 = Object.assign({}, obj)
console.log(obj1); // {name: '张三', age: 20}
只能深度拷贝对象的第一层,如果对象中的属性也是对象的话,没有办法进行深度copy
5、循环递归进行copy
function deepClone(obj, newObj) {
var newObj = newObj || {}
for (const key in obj) {
if (typeof obj[key] == 'object') {
newObj[key] = (obj[key].constructor === Array) ? [] : {}
deepClone(obj[key], newObj[key])
} else {
newObj[key] = obj[key]
}
}
console.log(newObj); // {name: '张三', age: 20}
return newObj
}
let obj = { name: '张三', age: 20 }
deepClone(obj)
循环递归的时候要设置临界值(typeof obj[key] == 'object'),避免造成死循环。
使用循环递归的方式可以处理对象嵌套数组或者对象的问题。相当于for in遍历copy的优化版本。
扩展方法
1、通过jQuery的extend方法实现深拷贝
var array = [1,2,3,4];
var newArray = $.extend(true,[],array);
2、lodash函数库实现深拷贝
lodash很热门的函数库,提供了 lodash.cloneDeep()实现深拷贝
\