2015-03-31 5 views
2

В настоящее время я изучаю JS и ES6. У меня возникли проблемы с пониманием того, почему мой код с конструктором классов и функциями стрелок не работает без нескольких изменений.Объяснение эффекта конструктора классов 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 представляют собой массив с нулевой длиной, а не фактически, umm, имеющий аргументы.

Чтобы получить код работает, я изменил его к этому:

// 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. используя функцию обратного вызова вместо функции стрелки.

Пожалуйста, объясните, почему forEach с встроенным массивом выходит из строя и почему из списка аргументов сбой из-за функции стрелки.

Также, вопрос о бонусе, почему this в'this.stores.foreach 'привязан к экземпляру моего объекта, а не к примеру. событие, вызывающее вызов функции?

+0

Вы по-прежнему получаете ошибки, если используете разделители ';'? У вас, похоже, есть аллергия на них –

+0

Правильно, недостающая точка с запятой была причиной ошибки № 1. Я не страдаю аллергией, но несколько библиотек, на которые я смотрел, похоже, не содержат разделителей. Мне просто нужно изучить правила и принять конвенцию, чтобы использовать или не использовать их. Однако использование их кажется более безопасным. –

ответ

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) приводит к арг быть нулевой длины массива, а не на самом деле, гм, имея аргументы.

В функциях стрелки, как this и arguments являются лексической областью видимости. То есть функции стрелки не имеют собственного объекта arguments.

+0

Спасибо, отличный ответ! Теперь вы поняли, что объяснили это. –

+0

Если бы вы могли, отредактируйте эту опечатку в своем ответе: «Это» относится к зависимости от того, как вызывается функция, которую вы не должны показывать [=> нет]. –

Смежные вопросы