【问题标题】:Array.prototype.filter() argument with arrow function callback? (no this binding)带有箭头函数回调的 Array.prototype.filter() 参数? (没有这个绑定)
【发布时间】:2017-08-31 21:35:47
【问题描述】:

受this article 的启发,我一直在重构一些旧代码。

但是,我在使用Array.prototype.filter 传递参数时遇到了问题,因为Array.prototype.filter(callback, thisArg) 的第二个参数在回调中绑定了this-object,但箭头函数不绑定this。

在我的示例中,我使用 Object.keys() 从关联数组中获取键(是的,我知道,技术上在 JavaScript 中不可用),然后通过关联数组 @987654328 中对象的属性过滤该数组@,但由于此绑定不可用,因此失败。

那么,拥抱箭头函数,如何将参数传递给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);

【问题讨论】:

  • 箭头函数不绑定到这里自己的developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 为什么首先需要涉及this? .filter(v => arr[v].property) 非常易读且简短。
  • hasProperty 和 getMatchingKeys 真的应该在 arr 对象字面量内吗?
  • 如果您需要 this 作为方法上下文,请不要使用箭头函数。
  • "所以,拥抱箭头函数" - 这显然是错误的态度。一个人应该只在有用的地方使用箭头,而不应该尝试在它们不起作用的地方使用它们。

标签: javascript arrays ecmascript-6 arrow-functions


【解决方案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 中的一些其他选项。

【讨论】:

  • 我无法让它工作?对我来说,它产生与使用键相同的数组?
  • 它对我来说并不相同。我添加了一个具有property: false 的c 属性:输出将只有a 和b,因为只有那些有property: true。这不是你想要的输出吗?然后您可以编辑您的问题并指定所需的输出是什么吗?
  • 谢谢,这个更新的 sn-p 确实产生了不同的结果,过滤是正确的,但不幸的是返回的数组不是,这返回了一个对象数组,没有键,而想要的结果是一个键数组。
  • 我根据该要求调整了答案。
【解决方案2】:

文章作者提供了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 在原始帖子的 cmets 中提供(深埋,张贴在这里以提高知名度):

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

【讨论】:

    猜你喜欢
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    相关资源
    最近更新 更多