|
|
|
|
@ -32,29 +32,37 @@ var hasOwnProperty = Object.prototype.hasOwnProperty
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
function merge(dest, src, redefine) {
|
|
|
|
|
// 检查目标对象(dest)是否存在,如果不存在则抛出类型错误,表明目标对象参数是必需的
|
|
|
|
|
if (!dest) {
|
|
|
|
|
throw new TypeError('argument dest is required')
|
|
|
|
|
throw new TypeError('argument dest is required');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查源对象(src)是否存在,如果不存在则抛出类型错误,表明源对象参数是必需的
|
|
|
|
|
if (!src) {
|
|
|
|
|
throw new TypeError('argument src is required')
|
|
|
|
|
throw new TypeError('argument src is required');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果redefine参数未被传入(即值为undefined),则将其默认设置为true
|
|
|
|
|
if (redefine === undefined) {
|
|
|
|
|
// Default to true
|
|
|
|
|
redefine = true
|
|
|
|
|
redefine = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 遍历源对象(src)自身的所有可枚举属性名(不包括继承属性)
|
|
|
|
|
Object.getOwnPropertyNames(src).forEach(function forEachOwnPropertyName(name) {
|
|
|
|
|
// 如果redefine为false,并且目标对象(dest)已经拥有当前遍历到的属性名对应的属性
|
|
|
|
|
// 那么跳过该属性的处理,直接进入下一次循环
|
|
|
|
|
if (!redefine && hasOwnProperty.call(dest, name)) {
|
|
|
|
|
// Skip desriptor
|
|
|
|
|
return
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Copy descriptor
|
|
|
|
|
var descriptor = Object.getOwnPropertyDescriptor(src, name)
|
|
|
|
|
Object.defineProperty(dest, name, descriptor)
|
|
|
|
|
})
|
|
|
|
|
// 获取源对象(src)中当前属性名对应的属性描述符(包括属性值、可写性、可枚举性、可配置性等信息)
|
|
|
|
|
var descriptor = Object.getOwnPropertyDescriptor(src, name);
|
|
|
|
|
// 使用获取到的属性描述符,在目标对象(dest)上定义同名属性,实现将源对象的属性复制到目标对象上
|
|
|
|
|
Object.defineProperty(dest, name, descriptor);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return dest
|
|
|
|
|
}
|
|
|
|
|
// 返回合并后的目标对象(dest),此时它已经包含了从源对象复制过来的属性(根据redefine规则)
|
|
|
|
|
return dest;
|
|
|
|
|
}
|