最简单的方法是复制JS对象并过滤掉某些属性

时间:2016-10-11 07:37:10

标签: javascript ecmascript-6

如果我有一个JS对象,并且我想创建一个新对象,该对象复制除了需要过滤掉的属性黑名单之外的所有属性,那么最简单的方法是什么?

所以我会做类似

的事情
Public Sub progress(pctCompl As Single)
    Me.Text.Caption = Format(pctCompl, "##") & "% Completed"
    Me.Bar.Width = pctCompl * 2
    Me.Repaint
End Sub

Public Sub setMessage(message As String, Optional percentage As Single = 0#)
    If Not ProgressBar.Visible Then ProgressBar.Show vbModeless
    ProgressBar.Label_WhatsGoingOn.Caption = message
    If percentage <> 0 Then Call ProgressBar.progress(percentage)
End Sub

将使用原始对象,复制它,并确保属性originalObject.copyAndFilter('a', 'b') a不在新对象中。

我正在使用通过Babel的ES2015 / 2016,所以如果它提供了一种更简单的方式也可以使用。

6 个答案:

答案 0 :(得分:2)

您可以使用Set并删除不需要的属性。

var object = { a: 1, b: 2, c: 3, d: 4 },
    filteredObject = {},
    p = new Set(Object.keys(object));
    blacklist = ['a', 'b'];

blacklist.forEach(a => p.delete(a));

[...p].forEach(k => filteredObject[k] = object[k]);
console.log(filteredObject);

答案 1 :(得分:1)

嗯,没有简单的原生方式,我会将键转换为数组,过滤它,然后创建一个新对象:

&#13;
&#13;
const obj = {a: 'foo', b: 'bar', c: 'baz'};
const blacklist = ['a', 'b'];

const keys = Object.keys(obj);
const filteredKeys = keys.filter(key => !blacklist.includes(key));

const filteredObj = filteredKeys.reduce((result, key) => {
  result[key] = obj[key];
  return result;
}, {});

console.log(filteredObj);
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以循环遍历对象键并创建新对象。您甚至可以使用for...in。这将增加所有浏览器都支持的优势。

var obj = {a: 'foo', b: 'bar', c: 'baz'};
var blackListKeys = ['a', 'b','z'];
var obj2 = {}
for(var k in obj){
  if(blackListKeys.indexOf(k) === -1)
    obj2[k] = obj[k];
}
console.log(obj2)

答案 3 :(得分:0)

&#13;
&#13;
var obj = {foo: 1, a: 2, b:3}
var newObj = {}
var blacklist = ['a', 'b']

for(let [key, value] of Object.entries(obj)) {
  !blacklist.includes(key) && (newObj[key] = value)
}

console.log(newObj)
&#13;
&#13;
&#13;

变量较少:

&#13;
&#13;
var obj = {foo: 1, a: 2, b: 3}

var newObj = Object.entries(obj)
  .filter(([key, val]) => !['a', 'b'].includes(key))
  .reduce((newObj, [key, value]) => (newObj[key] = value, newObj), {})

console.log(newObj)
&#13;
&#13;
&#13;

答案 4 :(得分:0)

我认为Object.assign是最好的ES5实用程序,只需要很少的额外逻辑就可以实现:

function copyAndFilter(...args){ 
    var copy = Object.assign( {} , this);

    args.forEach(prop => { 
        delete copy[prop];
    }); return copy;
}

然后:

var a = {foo : 'foo' , bar : 'bar'};
a.copyAndFilter = /* function definition above*/
a.copyAndFilter('foo');// { bar : 'bar' }

答案 5 :(得分:0)

这里有两个问题:

第一个实际上是在没有引用的情况下复制对象。

如果只是循环对象键并从原始对象执行其值的赋值,如果该值也是对象,则最终引用该对象(甚至是数组),而不是复制自身。因此,您需要检测并递归调用 copy_object 函数以避免引用。

幸运的是,在一些提供对象 extend()函数的库中已经解决了这个问题,例如npm(服务器端)和jQuery(浏览器)。

技巧仅包括扩展新创建的对象:

var dst_object = extend({}, src_object);

第二个问题是为了避免不受欢迎的密钥。

这里有可能的方法:一种方法是在前面提到的extend()函数中完全重新实现它们提供黑名单功能的方式。

...第二个(并且不易出错)是在复制对象后简单地删除不需要的密钥。如果它们不是庞大的数据结构,那么开销将是微不足道的。

示例:

// npm install --save extend
var extend = require("extend");
function oClone(target, blacklist) {
    var dest = extend({}, target);
    if (blacklist) {
        for (var i=0; i<blacklist.length; i++) {
            delete (dest[blacklist[i]]);
        };
    };
    return dest;
};