2014-11-01 6 views
3

Экстремальные функции 6 символов кажутся идеально подходящими для использования в качестве методов в классах, поскольку они не подвержены вызывающему контексту, возиться с «этой» ссылкой. Я не могу понять, как использовать их так, как я ожидаю. Следующий класс, который показывает два пути я могу видеть, чтобы использовать их:Каков правильный способ использования функций стрелок Ecmascript 6 как методов в классах?

class Person { 

constructor(aName) { 
    this.name = aName; 
    this.say2 =() => console.log(this.name); 
} 

say() { console.log(this.name) } 

say3() {() => consolve.log(this.name) } 

} 

Оба say2 и say3 будет использовать новое это обращение и один должен быть в состоянии передать их щелкать обработчики, а также другие функции нуждаясь обратные вызовы и не нужно беспокоиться о том, что вызывающий вызов вызывается в некоторых случаях, что приводит к тому, что «это» неожиданно указывает на нечто иное, чем соответствующий экземпляр объекта.

Оба say2 и say3 кажутся неудобными. say2 определяется в конструкторе, а say3 действительно является оберткой вокруг функций стрелок. Я ожидал, что некоторый sytax, которая позволила бы мне заменить строку скажет() с чем-то вроде

say:() => console.log(this.name) 

Но насколько я могу судить, вы не можете ничего подобного делать. Поэтому вопрос заключается в том, чтобы использовать функции стрелок, поскольку методы - это подход say2 или say3 разумный. Есть ли способ лучше?

Спасибо за любой ввод.

ответ

1

В грамматике ES6 the body of a class может состоять только из method definitions, поэтому выражения функции стрелки здесь запрещены. Это упрощенное фрагмент из соответствующих частей грамматики:

ClassBody : 
    ClassElementList 

ClassElementList : 
    ClassElement 
    ClassElementList ClassElement 

ClassElement : 
    MethodDefinition 
    static MethodDefinition 
    ; 

MethodDefinition : 
    PropertyName (StrictFormalParameters) { FunctionBody } 
    GeneratorMethod 
    get PropertyName () { FunctionBody } 
    set PropertyName (PropertySetParameterList) { FunctionBody } 

Таким образом, в вашем примере:

class Person { 

    constructor(aName) { 
     this.name = aName; 
     this.say2 =() => console.log(this.name); 
    } 

    say() { console.log(this.name) } 

    say3() {() => console.log(this.name) } 

} 
  • say является нормальным определение метода, который страдает от тех же проблем, с this связывания как нормальные функции. Однако вы можете обойти это, используя bind, когда вы его передаете, как в element.addEventListener('click', this.say.bind(this));.
  • say2 будет работать, но вы потеряете удобство указания методов вне конструктора.
  • say3 не будет работать - хотя он синтаксически действителен, он будет анализироваться как метод, тело которого состоит из одной функции стрелки. Чтобы уточнить, say3() {() => console.log(this.name) } и say3() { return() => console.log(this.name) } отличаются тем, что первый ничего не сделает и возвращает undefined, тогда как последний вернет выражение функции стрелки, которое при вызове будет напечатано на консоли.