![](/img/trans.png)
[英]What is the most elegant way to remove an array of properties from an object immutably in JavaScript?
[英]Most elegant way to save only primitive properties of a Javascript object
我有一个拥有很多自己的和继承的方法的对象。 我只需要用原始属性制作一个简单的快照。
最优雅的方法是什么?
Javascript片段
function copy(source) {
var target;
if (source) {
target = {};
for (var key in source) {
var prop = source[key],
type = typeof prop;
if (type === "string" || type === "number" || type === "boolean") {
target[key] = prop;
}
if (type == "object") {
target[key] = copy(prop);
}
}
}
return target;
}
function copy(source) {
var target;
if (source) {
target = {};
_.filter( _.keys(source), function( key ) {
var prop = source[key];
if (!_.isFunction(prop) && !_.isObject(prop)) {
target[key] = prop;
}
if (_.isObject(prop)) {
target[key] = copy(prop);
}
});
}
return target;
}
这里的问题是,由于JavaScript提供的松散类型,您正在处理的混合类型可能是或可能不是您想要的。 特别是,如果不遍历任何给定的数组,就无法判断它是否仅包含基元,因此您可能想要保留它,或者它是否包含要过滤掉的对象或函数。
我知道图书馆的建议是最古老的帽子,但我也要去强烈建议您使用Underscore.js (或如衍生Lodash ),这也是一大堆,我用的全部时间超方便的功能。 从真正的意义上讲,这些感觉就像是核心JavaScript语言的缺失部分-实际上,在某些情况下,它们包装了本机功能,但允许您避免平台不一致。
如果您的库中包含Underscore,则可以找到任何给定对象的非对象属性名称,如下所示:
var myObject = {
a: "hello",
b: "goodbye",
c: function() { console.log(this.b);}
d: { hello: "banana" }
};
_.filter( _.keys(myObject), function( key ) {
return ! _.isObject(myObject[key]);
}) // => ["a", "b"]
然后可以将其整理为用于克隆对象的函数,但是当然这是不必要的,因为_.pick
为我们提供了_.pick
,它返回仅具有白名单属性的对象副本:
_.pick( myObject, _.filter( _.keys(myObject), function( key ) { return ! _.isObject(myObject[key]);}))
通过翻转!_.isObject
您可以检索作为对象的所有属性,并在必要时对这些属性执行类似的映射。 通过将两个函数包装在一起,可以在要克隆的子对象上递归调用它。
这回答了您的问题,但是请注意,这可能不是执行撤消/重做操作的最佳方法,您在注释中提到的是计划将其用于此的用途。 将动作和状态记录到历史记录堆栈中可能更容易,该记录仅记录任何动作执行的实际更改,在其中可以安全地检索和还原它们,而无需保留数据快照。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.