繁体   English   中英

仅保存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;
}

使用Underscore.js

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM