JavaScript:对象的filter()

如果我理解正确,ECMAScript 5具有Arraytypes的filter()原型,但不包含Objecttypes。

我将如何实现一个filter()在JavaScript中的Object

比方说,我有这个对象:

 var foo = { bar: "Yes" }; 

我想写一个filter()Object上工作:

 Object.prototype.filter = function(predicate) { var result = {}; for (key in this) { if (this.hasOwnProperty(key) && !predicate(this[key])) { result[key] = this[key]; } } return result; }; 

这个工程,当我在下面的演示中使用它,但是当我将它添加到我的网站,使用jQuery 1.5和jQuery UI 1.8.9,我在FireBug中得到JavaScript错误。

 Object.prototype.filter = function(predicate) { var result = {}; for (key in this) { if (this.hasOwnProperty(key) && !predicate(this[key])) { console.log("copying"); result[key] = this[key]; } } return result; }; var foo = { bar: "Yes", moo: undefined }; foo = foo.filter(function(property) { return typeof property === "undefined"; }); document.getElementById('disp').innerHTML = JSON.stringify(foo, undefined, ' '); console.log(foo); 
 #disp { white-space: pre; font-family: monospace } 
 <div id="disp"></div> 

永远不要扩展Object.prototype

可怕的事情会发生在你的代码。 事情会打破。 您正在扩展所有对象types,包括对象文字。

下面是一个可以尝试的简单例子:

  // Extend Object.prototype Object.prototype.extended = "I'm everywhere!"; // See the result alert( {}.extended ); // "I'm everywhere!" alert( [].extended ); // "I'm everywhere!" alert( new Date().extended ); // "I'm everywhere!" alert( 3..extended ); // "I'm everywhere!" alert( true.extended ); // "I'm everywhere!" alert( "here?".extended ); // "I'm everywhere!" 

而是创build一个你传递对象的函数。

 Object.filter = function( obj, predicate) { var result = {}, key; // ---------------^---- as noted by @CMS, // always declare variables with the "var" keyword for (key in obj) { if (obj.hasOwnProperty(key) && !predicate(obj[key])) { result[key] = obj[key]; } } return result; }; 

您也可以使用reduceObject.keys来实现这一点(使用ES6 箭头语法 ):

 Object.filter = (obj, predicate) => Object.keys(obj) .filter( key => predicate(obj[key]) ) .reduce( (res, key) => (res[key] = obj[key], res), {} ); // Example use: var scores = { John: 2, Sarah: 3, Janet: 1 }; var filtered = Object.filter(scores, score => score > 1); console.log(filtered); 

如果你愿意使用下划线lodash ,你可以使用pick (或者相反, omit )。

下划线的文档示例:

 _.pick({name: 'moe', age: 50, userid: 'moe1'}, 'name', 'age'); // {name: 'moe', age: 50} 

或者用callback(对于lodash ,使用pickBy ):

 _.pick({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object) { return _.isNumber(value); }); // {age: 50} 

正如帕特里克已经表示,这是一个坏主意,因为它几乎肯定会打破任何第三方代码,你可能会希望使用。

如果扩展Object.prototype ,所有库(如jquery或prototype)都会中断,原因是由于添加的函数将成为迭代的一部分,所以对对象的懒惰迭代(不包含hasOwnProperty检查)将会中断。

我已经创build了一个Object.filter() ,它不仅可以通过函数进行过滤,还可以接受包含的数组。 可选的第三个参数将允许您反转filter。

鉴于:

 var foo = { x: 1, y: 0, z: -1, a: 'Hello', b: 'World' } 

阵:

 Object.filter(foo, ['z', 'a', 'b'], true); 

function:

 Object.filter(foo, function (key, value) { return Ext.isString(value); }); 

免责声明 :为了简洁,我select使用Ext JS内核。 没有觉得有必要为对象types编写types检查器,因为它不是问题的一部分。

 // Helper functions function clone(obj) { return JSON.parse(JSON.stringify(obj)); } function print(obj) { document.getElementById('disp').innerHTML += JSON.stringify(obj, undefined, ' ') + '<br />'; console.log(obj); } Object.filter = function (obj, ignore, invert) { if (ignore === undefined) { return obj; } invert = invert || false; var not = function(condition, yes) { return yes ? !condition : condition; }; var isArray = Ext.isArray(ignore); for (var key in obj) { if (obj.hasOwnProperty(key) && (isArray && not(!Ext.Array.contains(ignore, key), invert)) || (!isArray && not(!ignore.call(undefined, key, obj[key]), invert))) { delete obj[key]; } } return obj; }; var foo = { x: 1, y: 0, z: -1, a: 'Hello', b: 'World' }, bar = clone(foo); print(Object.filter(foo, ['z', 'a', 'b'], true)); print(Object.filter(bar, function (key, value) { return Ext.isString(value); })); 
 #disp { white-space: pre; font-family: monospace } 
 <script src="ajax/libs/extjs/4.2.1/builds/ext-core.min.js"></script> <div id="disp"></div> 

怎么样:

 function filterObj(keys, obj) { const newObj = {}; for (let key in obj) { if (keys.includes(key)) { newObj[key] = obj[key]; } } return newObj; } 

要么…

 function filterObj(keys, obj) { const newObj = {}; Object.keys(obj).forEach(key => { if (keys.includes(key)) { newObj[key] = obj[key]; } }); return newObj; } 

特定

 object = {firstname: 'abd', lastname:'tm', age:16, school:'insat'}; keys = ['firstname', 'age']; 

然后 :

 keys.reduce((a, b) =>{ a[b]=object[b] ; return a},{}); // {firstname:'abd', age: 16}