递归方法实现深拷贝原理:
遍历对象、数组直到里面的都是基本数据类型,然后再去赋值,就是深拷贝。
// 深拷贝:JSON.parse(JSON.stringfy(obj))会导致对象中Date RegExp Function的成员克隆失败,
// 但是大部分项目的情形都可以使用
function deepClone(obj) {
// 过滤特殊情况
if (obj === null) return obj
if (obj === undefined) return undefined // typeof undefined === 'undefined'
// 下面这一行代码,是为了过滤基本数据类型
// 除了Object之外,
//剩下的都是基本数据类型:null undefined string number boolean BigInt Symbol
if (typeof obj !== 'object') return obj
if (obj instanceof Date) return new Date(obj)
if (obj instanceof RegExp) return new RegExp(obj)
if (obj instanceof Function) return new Function(obj)
// JS中常用的内置对象:Array对象、Date对象、正则表达式对象、string对象、Global对象
// javascript的11种内置对象:
// Array
// String
// Date
// Math
// Boolean
// Number
// Function
// Global
// Error
// RegExp
// Object
// 下面这一行代码:不直接创建空对象,克隆的结果和之前保持相同所属的类
let cloneObj = new obj.constructor
for (let key in obj) { // key为属性,obj[key]为对应的属性值
// hasOwnProperty() 方法用来检测一个属性是否是对象的自有属性,而不是从原型链继承的
if (obj.hasOwnProperty(key)) {
cloneObj[key] = deepClone(obj[key]) // 给新克隆对象的属性赋值
}
}
return cloneObj
}
在使用for in循环时,返回的是所有能够通过对象访问的、可枚举的属性,其中既包括存在于实例中的属性,也包括存在于原型中的属性。
所以使用 hasOwnProperty 方法,只遍历对象自身的属性,而不包含继承于原型链上的属性。