【问题标题】:array method(s) inaccessible with MyObject.prototype.reduce callbackMyObject.prototype.reduce 回调无法访问数组方法
【发布时间】:2019-06-22 19:08:53
【问题描述】:

所以,我正在尝试一些原型设计,并且已经成功地在原型上实现 forEach 以处理其对象数组。箭头函数回调工作正常,我认为同样的事情可能适用于 .reduce(),但是,如您所见,适用于普通 Array 的符号不适用于我的 ArraySet 原型。附带说明一下,箭头符号中的相同功能不起作用。

我对这里发生的事情的理解中缺少什么以便我可以解决这个问题并继续前进?

function ArraySet(items) {
  // this._items = []
  this._items = items
}

ArraySet.prototype.forEach = function forEach(cb) {
   return this._items.forEach(cb);
}
  
ArraySet.prototype.reduce = function reduce(cb) {
  return this._items.reduce(cb);
}

let arr = new ArraySet([{
    key1: 'property2',
    key3: 'propertyx'
  },
  {
    key1: 'property4',
    key3: 'propertyy'
  },
  {
    key1: 'climate change',
    key3: 'propertyx'
  },
  {
    key1: 'climate change',
    key3: 'propertyx'
  },
])

arr.forEach(el => {
    console.log(el)
});

x = arr.reduce(function (map, obj) {
    if (obj.key3 === 'propertyx'){
        map.push(obj.key1)
    }
    return map
}, []) //<-- final argument is the instantiating literal of the reigning map type: [], {}, ''

编辑: 感谢 Maheer Ali 的回答,详细说明了扩展运算符 (...) 的使用,问题很容易解决。 Maheer 出色地扩展了适用相同方法的其他功能。

深入研究原因,我在展开运算符出现之前了解到 .apply() 通常用于函数调用,以确保所有必需的参数在执行中可用。扩展运算符已从适用于数组(如参数列表)发展,因为它被引入也包括对象。它还可以复制一个数组,替换 arr.splice()。

这是对 MDN 上一个示例的改编:

function myFunction(v, w, x, y, ...z) {
  console.log(v + ' ' + w + ' ' + x + ' ' + y + ' ' + z)
}
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3, 8]);

更多可参考资料:Spread Syntax

【问题讨论】:

  • 这是因为你没有将init值传递给_items.reduce中的内置reduce

标签: javascript arrays callback reduce spread


【解决方案1】:

reduce() 有两个参数,一是回调,二是累加器的初始值。所以你需要为方法使用rest参数,然后将所有参数传递给reduce()

注意:reduce() 你通常传递第二个参数。在forEach(),map() 中还有第二个可选参数。该参数将this 绑定到传递给特定方法的回调。如果您需要使用该参数,请确保执行与reduce() 相同的操作

查看下面的工作 sn-p

function ArraySet(items) {
  // this._items = []
  this._items = items
}

ArraySet.prototype.forEach = function forEach(cb) {
   return this._items.forEach(cb);
}
  
ArraySet.prototype.reduce = function reduce(...args) {
  return this._items.reduce(...args);
}

let arr = new ArraySet([{
    key1: 'property2',
    key3: 'propertyx'
  },
  {
    key1: 'property4',
    key3: 'propertyy'
  },
  {
    key1: 'climate change',
    key3: 'propertyx'
  },
  {
    key1: 'climate change',
    key3: 'propertyx'
  },
])

arr.forEach(el => {
    console.log(el)
});

x = arr.reduce((map, obj) => {
    if (obj.key3 === 'propertyx'){
        map.push(obj.key1)
    }
    return map
}, []) //<-- final argument is the instantiating literal of the reigning map type: [], {}, ''

console.log(x)

顺便说一句,箭头符号中的相同功能不起作用

箭头函数没有自己的this 绑定。他们使用父范围的this。由于您在方法中使用this,因此您不能使用箭头函数。原型方法永远不能用箭头函数编写。

【讨论】:

  • 我应该澄清我对箭头函数的观察;它应该是“......箭头符号中的相同函数调用不起作用。”。在我发表评论时,我的想法是按照某种方式涉及函数调用,而不是如何处理参数列表。在您的修复中,箭头函数进行调用。您的回答的彻底性让我很高兴能够做到这一点,因为有关没有“this”的箭头函数的局限性以及围绕它们在原型方法组合中尝试使用的含义的信息确实使答案更加圆润。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
  • 2018-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多