基于模板克隆一个对象。如果你不想要完全相同的副本,但是你想要某种可靠的克隆操作的健壮性,而且你只想要一些位被克隆或者你想要确保你可以控制每个属性值的存在或格式被克隆,那么该怎么办呢?
我提供这个内容是因为它对我们很有用,而且我们创建它是因为我们找不到类似的东西。你可以使用它来基于指定要克隆的对象的属性的“模板”对象来克隆一个对象,并且模板允许函数将这些属性转换为不同的东西,如果它们不存在于源对象上或者无论你如何处理克隆。如果这不是有用的,我相信有人可以删除这个答案。
function isFunction(functionToCheck) {
var getType = {};
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}
function cloneObjectByTemplate(obj, tpl, cloneConstructor) {
if (typeof cloneConstructor === "undefined") {
cloneConstructor = false;
}
if (obj == null || typeof (obj) != 'object') return obj;
if (Array.isArray(obj)) {
var ret = [];
for (var i = 0; i < obj.length; i++) {
ret.push(cloneObjectByTemplate(obj[i], tpl, cloneConstructor));
}
return ret;
}
var temp = cloneConstructor ? new obj.constructor() : {};
for (var key in tpl) {
if (isFunction(tpl[key])) {
temp[key] = tpl[key](obj);
} else {
if (obj[key] != undefined) {
if (Array.isArray(obj[key])) {
temp[key] = [];
for (var i = 0; i < obj[key].length; i++) {
temp[key].push(cloneObjectByTemplate(obj[key][i], tpl[key], cloneConstructor));
}
} else {
temp[key] = cloneObjectByTemplate(obj[key], tpl[key], cloneConstructor);
}
}
}
}
return temp;
}
一个简单的调用方式如下所示:
var source = {
a: "whatever",
b: {
x: "yeah",
y: "haha"
}
};
var template = {
a: true,
b: {
x: true
}
};
var destination = cloneObjectByTemplate(source, template);
如果你想使用一个函数来确保返回一个属性或确保它是一个特定的类型,可以使用以下模板。我们提供了一个函数,而不是使用{ ID: true }
,这个函数仍然只是复制源对象的ID属性
,但它确保即使在源对象中不存在该属性,也会将其转换为数字。
var template = {
ID: function (srcObj) {
if(srcObj.ID == undefined){ return -1; }
return parseInt(srcObj.ID.toString());
}
}
数组可以克隆,但如果您想要的话,您也可以编写自己的函数来处理这些单独的属性,并执行类似于以下的特殊操作:
var template = {
tags: function (srcObj) {
var tags = [];
if (process.tags != undefined) {
for (var i = 0; i < process.tags.length; i++) {
tags.push(cloneObjectByTemplate(
srcObj.tags[i],
{ a : true, b : true }
);
}
}
return tags;
}
}
所以在上面的示例中,如果源对象存在
tags
属性(假设它是一个数组),我们的模板只是复制它,并且针对该数组中的每个元素都调用clone函数来基于第二个模板分别克隆它,该模板只是复制这些标签元素的
a
和
b
属性。如果你正在将对象带进和带出node.js,并且想要控制克隆这些对象的哪些属性,则这是一种很好的控制方法,而且此代码也适用于浏览器。以下是其使用示例:
http://jsfiddle.net/hjchyLt1/。
mObj=JSON.parse(JSON.stringify(jsonObject));
。 - Lord Loh.Object.create(o)
,它完全满足了作者的要求。 - froginvasionvar x = { deep: { key: 1 } }; var y = Object.create(x); x.deep.key = 2;
执行完这段代码后,y.deep.key
的值也会变成2,因此 Object.create 不能用于克隆对象。 - Ruben Stolk