手写深拷贝

141 阅读1分钟

递归方法实现深拷贝原理:
遍历对象、数组直到里面的都是基本数据类型,然后再去赋值,就是深拷贝。

// 深拷贝: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 方法,只遍历对象自身的属性,而不包含继承于原型链上的属性。