为什么我的函数的es6版本说"无法阅读属性' forEach'未定义"

时间:2015-11-28 14:54:48

标签: function ecmascript-6

这个版本的es6功能不起作用:

Array.prototype.concatAll = () => {
  let results = [];

  this.forEach((subArray) => {
    subArray.forEach((item) => {
      results.push(item);
    });
  });

  return results;
};

当我像这样使用它时:

var stocks = exchanges.concatAll();

控制台说:Cannot read property 'forEach' of undefined

然而,这个es5版本运行得很好:

Array.prototype.concatAll = function() {
  let results = [];

  this.forEach((subArray) => {
    subArray.forEach((item) => {
      results.push(item);
    });
  });

  return results;
};

这是为什么? es6版本中this究竟发生了什么?我想了解。

2 个答案:

答案 0 :(得分:2)

已经提到过这一点,但由于它们绑定了this的值,因此箭头函数不是一个很好的用例。使用ES6执行此操作的另一种方法是使用Object.assign

对于你的例子:

Object.assign(Array.prototype, {
  concatAll() {
    let results = [];

    this.forEach(subArr => {
      subArr.forEach(item => {
        results.push(item);
      });
    });

    return results;
  }
});

然后你可以使用这样的代码:

let arr = [
  [1, 2, 3],
  [4, 5, 6]
];

console.log(arr.concatAll()); // -> [1, 2, 3, 4, 5, 6]

您还可以添加以下多种方法:

Object.assign(Array.prototype, {
  sum() {
    return this.reduce((a, b) => a + b);
  },

  max() {
    return this.reduce((a, b) => (a > b) ? a : b);
  },

  min() {
    return this.reduce((a, b) => (a < b) ? a : b);
  }
});

let arr = [1, 2, 3];

console.log(arr.sum()); // -> 6
console.log(arr.max()); // -> 3
console.log(arr.min()); // -> 1

答案 1 :(得分:0)

箭头函数this的范围是它的父范围。所以在这种情况下this是未定义的。所以在这种情况下你仍然需要一个函数。

检查https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions的开头。

  

与函数表达式相比,箭头函数表达式(也称为胖箭头函数)具有更短的语法,并且以词汇方式绑定此值(不绑定其自身的this,arguments,super或new.target)< / strong>即可。箭头功能始终是匿名的。

通过使用for of

,ES6仍然可以简化您的代码
Array.prototype.concatAll = function(){
  let results = []
  for(let subArray of this)
    for(let item of subArray)
      results.push(item)
  return results
}