2017-08-31 115 views
0

编辑:这已被错误地标记为重复数据删除技术(见注释讨论)解决这一特定问题是由文章作者here带有箭头函数回调的Array.prototype.filter()参数? (没有这种绑定)

https://hackernoon.com/rethinking-javascript-death-of-the-for-loop-c431564c84a8提供启发我已经重构了一些旧码。

由于Array.prototype.filter(callback,thisArg)的第二个参数在回调中绑定了“this”对象,但箭头函数不绑定“this ”。

在我的示例中,我通过使用“Object.keys()”从关联数组中获取关键字(是的,我知道,技术上在js中不可用),然后通过其对象的属性关联数组“this [item] .property”,但由于此绑定不可用而失败。

因此,拥抱箭头函数,如何将参数传递给filter()中的回调函数?

const arr = { 
 
    a: { 
 
     property: true, 
 
     otherProp: false 
 
    }, 
 
    b: { 
 
     property: true, 
 
     otherProp: false 
 
    }, 
 
    }, 
 
    hasProperty = item => this[item].property, 
 
    getMatchingKeys = object => Object.keys(object).filter(hasProperty, object); 
 
getMatchingKeys(arr);

+1

箭头函数不绑定到此上自己https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – TimCodes

+2

为什么它需要首先涉及'this'? '.filter(v => arr [v] .property)'已经非常可读和简短了。 – loganfsmyth

+0

'hasProperty'和'getMatchingKeys'是否应该在'arr'对象字面值内? – Barmar

回答

1

您可以使用Object.entries。它同时提供键和值,这样你就不需要参考对象本身:

const arr = { 
 
     a: { 
 
      property: true, 
 
      otherProp: false 
 
     }, 
 
     b: { 
 
      property: true, 
 
      otherProp: false 
 
     }, 
 
     c: { 
 
      property: false, // to be excluded 
 
      otherProp: true 
 
     }, 
 
    }, 
 
    hasProperty = ([key, value]) => value.property, 
 
    first = ([key]) => key, 
 
    getMatchingKeys = object => Object.entries(object).filter(hasProperty).map(first); 
 

 
console.log(getMatchingKeys(arr));
.as-console-wrapper { max-height: 100% !important; top: 0; }

你也可以使用bind - 不结合this,但第一个参数:

const arr = { 
 
     a: { 
 
      property: true, 
 
      otherProp: false 
 
     }, 
 
     b: { 
 
      property: true, 
 
      otherProp: false 
 
     }, 
 
     c: { 
 
      property: false, // to be excluded 
 
      otherProp: true 
 
     }, 
 
    }, 
 
    hasProperty = (object, key) => object[key].property, 
 
    getMatchingKeys = object => Object.keys(object).filter(hasProperty.bind(null, arr)); 
 

 
console.log(getMatchingKeys(arr));
.as-console-wrapper { max-height: 100% !important; top: 0; }

另请参阅my answer to another question中的其他选项。

+0

我无法得到这个工作?对我来说,它产生与使用键相同的数组? – Hessius

+0

它不会为我产生同样的结果。我添加了一个'c'属性,它具有'property:false':输出将只有'a'和'b',因为只有那些'property:true'。这不是你想要的输出吗?你可以编辑你的问题,并指定期望的输出是什么? – trincot

+0

谢谢你,这个更新后的代码片段确实产生了不同的结果,过滤是正确的,但是返回的数组不幸运,这返回了一个没有键的对象数组,而想要的结果是一个键数组。 – Hessius

0

文章的作者提供一个answer in the comments,这里供参考:

const arr = { 
    a: { 
    property: true, 
    otherProp: false, 
    }, 
    b: { 
    property: true, 
    otherProp: false, 
    }, 
} 
const hasProperty = object => item => object[item].property 
const getMatchingKeys = object => Object.keys(object).filter(hasProperty(arr)) 
getMatchingKeys(arr) // = ['a', 'b'] 

进一步阅读,通过@bergi在原岗位的给予(深埋,贴在这里的更大的可视性):

  1. jQuery pass more parameters into callback
  2. How do I pass an extra parameter to the callback function in Javascript .filter() method?