解释ES6类构造函数和箭头函数的效果

时间:2015-03-31 19:09:59

标签: javascript arrays class module ecmascript-6

我目前正在学习JS和ES6。我无法理解为什么带有类构造函数和箭头函数的代码在没有一些更改的情况下无效。

这是我开始的地方,一个ES6模块导出这个类似通量的调度程序对象。

// RiotControl dispatcher formatted as ES6 module.
// https://github.com/jimsparkman/RiotControl

var dispatcher = {
  stores: [],
  addStore: function(store) {
    this.stores.push(store);
  }
};

['on','one','off','trigger'].forEach(function(api){
  dispatcher[api] = function() {
    var args = [].slice.call(arguments);
    this.stores.forEach(function(el){
      el[api].apply(null, args);
    });
  };
});

export default dispatcher

我想用这段代码创建一个类,最初最终得到:

// RiotControl dispatcher formatted as ES6 class module.
// https://github.com/jimsparkman/RiotControl

export default class {
  constructor() {        
    this.stores = []    
    this.addStore = store => {
      this.stores.push(store);
    }

    ['on','one','off','trigger'].forEach(fn => {
      this[fn] = () => {
        var args = [].slice.call(arguments)
        this.stores.forEach(function(el){
          el[fn].apply(null, args)
        })
      }
    })
  }
}

由于我不知道的原因,这不起作用。

  1. 第一个.forEach(...)会产生Uncaught TypeError: Cannot read property 'forEach' of undefined,就像未定义数组一样。
  2. var args = [].slice.call(arguments)导致args是一个零长度数组,而不是实际上,嗯,有参数。
  3. 为了使代码正常工作,我将其更改为:

    // RiotControl dispatcher formatted as ES6 class module.
    // https://github.com/jimsparkman/RiotControl
    
    export default class {
      constructor() {        
        this.stores = []    
        this.addStore = store => {
          this.stores.push(store);
        }
    
        var api = ['on','one','off','trigger']
        api.forEach(fn => {
          this[fn] = function() {
            var args = [].slice.call(arguments)
            this.stores.forEach(function(el){
              el[fn].apply(null, args)
            })
          }
        })
      }
    }
    

    因此,错误由

    确定
    1. 声明一个数组并在其上调用.forEach
    2. 使用常规回调函数代替箭头函数。
    3. 请解释为什么带有内联数组的forEach失败以及为什么在箭头函数内部对参数列表进行切片失败。

      另外,奖励问题,为什么'this.stores.foreach`中的this绑定到我的对象实例而不是例如导致函数被调用的事件?

1 个答案:

答案 0 :(得分:1)

  

请解释为什么带有内联数组的forEach失败以及为什么在箭头函数内部对参数列表进行切片失败。

代码解释如下:

this.addStore = store => { ... }['on','one','off','trigger'].forEach(...)
// which becomes
this.addStore = store => { ... }['trigger'].forEach(...)

即。您正在尝试访问函数的trigger属性,这当然不存在。在函数定义之后使用分号来显式终止赋值表达式:

this.addStore = store => {
  this.stores.push(store);
};
['on','one','off','trigger'].forEach(...);
  

另外,奖励问题,为什么this.stores.foreach中的这个绑定到我的对象实例而不是...导致函数被调用的事件?

this不受约束。 this引用的内容取决于函数的调用方式,您不应该显示该函数。


  

var args = [].slice.call(arguments)导致args是一个零长度数组而不是实际的,嗯,有参数。

在箭头函数中,thisarguments都是词法范围的。即箭头函数没有自己的arguments对象。