Open wordlex opened 3 years ago
对基本类型拷贝值,互不影响,对对象或数组只拷贝引用,无论修改新旧,两者都会发生变化。
对于对象完全拷贝一份,修改一个对象的属性也不会影响另一个。
function extend (deep, obj1, obj2) {
// 默认浅拷贝
var deep = false
// 第一个参数
var target = arguments[0] || {}
// 待拷贝的参数遍历索引
var i = 1
// 参数个数
var length = arguments.length
// 待拷贝的键值
var name
// 待拷贝的对象
var options
// 目标值
var src
// 待拷贝值
var copy
// 新的 src 值
var clone
// 检查第一个参数类型,判断深浅拷贝
if (typeof target === 'boolean') {
deep = target
target = arguments[1]
i++
}
if (typeof target !== 'object' || !isFunction(target)) {
// 如果目标不是对象或者函数则不能进行拷贝
target = {}
}
for (; i < length; i++) {
options = arguments[i]
for (name in options) {
src = target[name]
copy = options[name]
if (copy === target) {
// 简单的循环引用判断
continue
}
if (deep && copy && isPlainObject(copy) && (isPlainObject(copy) || (isCopyArray = Array.isArray(copy)))) {
// 递归调用的对象必须是对象或者是数组
if (isCopyArray) {
// 如果复制的是数组,需要检查目标值是否为数组
isCopyArray = false
clone = src && Array.isArray(src) ? src : []
} else {
// 对象同理
clone = src && isPlainObject(src) ? src : {}
}
// 深拷贝对象
// target[name] 不能用 src 替代,src 只是一个指针
target[name] = extend(deep, clone, copy)
} else if (copy !== undefined) {
// undefined 我们认为这个属性未定义/不需要,因此不需要复制
// 其他类型直接复制
target[name] = copy
}
}
}
return target
}
var a = { a: 1, b: 4 }
var b = { a: 1, b: [ 1, 2, 3] }
console.log(
extend(true, a, b)
)
什么是深拷贝、浅拷贝? 如何实现?