<script>
function cloneObject(sourceObj, targetObj) {
// 如果目标对象没有传参,我们就根据源对象的类型创建一个目标对象
// targetObj=targetObj || new sourceObj.constructor();
if (!targetObj) {
if (sourceObj.constructor === RegExp) {
targetObj = new RegExp(sourceObj.source, sourceObj.flags);
} else {
targetObj = new sourceObj.constructor();
}
}
// 将源对象的所有属性名以数组的形式获取
var names = Object.getOwnPropertyNames(sourceObj);
for (var i = 0; i < names.length; i++) {
// 根据每个属性名获取该对象的这个属性的描述对象(是否枚举,是否删除,是否可修改,value是值)
var desc = Object.getOwnPropertyDescriptor(sourceObj, names[i]);
// 如果描述对象的value是对象类型,他有引用并且非空,这种情况就需要对它的子对象进行复制
if (typeof (desc.value) === "object" && desc.value !== null) {
// 执行函数cloneObject,填入第一个参数,源对象,目标对象为空
// 函数最终会返回复制好的目标对象
var values = cloneObject(desc.value);
// 设置目标对象的描述对象除了value以外和源对象的描述内容相同
// value值设置为上面复制好的目标对象
Object.defineProperty(targetObj, names[i], {
enumerable: desc.enumerable,
writable: desc.writable,
configurable: desc.configurable,
value: values
})
} else {
// 如果该对象属性的描述对象的value是非引用值,直接给目标对象增加这个属性名,
// 并且将这个对象的描述对象赋值给这个新的属性
Object.defineProperty(targetObj, names[i], desc);
}
}
// 返回目标对象
return targetObj
}
</script>