ES6 геттер / сеттер з функцією стрілки


100

Я використовую babel6, і для свого проекту для домашніх тварин я створюю обгортку для XMLHttpRequest для методів, які я можу використовувати:

open = (method, url, something) => {
  return this.xhr.open(method, url, something);
}

але для властивостей функція стрілки не працює

це працює:

get status() { return this.xhr.status; }

але я не можу використовувати

get status = () => this.xhr.status;

Це навмисно?


Вам не потрібні фігурні дужки або повернення; можна просто сказати (method, url, something) => this.xhr.open(method. url, something).

getє частиною літерального об’єкта або визначенням класу, присвоєння змінної - ні. Чому, на вашу думку, вони повинні працювати однаково?
Бергі,

1
status => this.xhr.status(c # 7 синтаксис) або, можливо get status() => this.xhr.status, справді був би чудовим синтаксичним цукром для читабельності, але Javascript не Typescript (поки що?) не підтримує цього
Charles HETIER

Відповіді:


108

Згідно з граматикою ES2015, властивість літералу об’єкта може бути лише однією з чотирьох речей:

Визначення властивості :

  • IdentifierReference
  • PropertyName : AssignmentExpression
  • МетодВизначення

Єдиним із цих типів, який допускає провід, getє MethodDefinition :

Визначення методу :

  • PropertyName ( StrictFormalParameters ) { FunctionBody }
  • GeneratorMethod
  • get PropertyName ( ) { FunctionBody }
  • set PropertyName ( PropertySetParameterList ) { FunctionBody }

Як бачите, getформа відповідає дуже обмеженій граматиці, яка має бути такою

get NAME () { BODY }

Граматика не допускає функції форми get NAME = ....


Дякую за вашу допомогу, я приймаю вашу відповідь. Чи знаєте ви, де визначено, що геттер / сеттер не можна використовувати з присвоєнням? Просто цікаво.
Габор Долла,

@GaborDolla Відредаговано для посилання на граматику буквального об’єкта в специфікації ECMAScript.
apsillers

35

Прийнята відповідь чудова. Найкраще, якщо ви бажаєте використовувати звичайний синтаксис функції замість компактного "синтаксису функції стрілки".

Але, можливо, вам дуже подобаються функції стрілок; можливо, ви використовуєте функцію стрілки з іншої причини, яку звичайний синтаксис функції не може замінити ; Вам може знадобитися інше рішення.

Наприклад, я помічаю, як OP використовує this, можливо, ви захочете пов’язати thisлексично; він же "необов'язковість цього" ), а функції стрілок хороші для цього лексичного прив'язки.

Ви все ще можете використовувати функцію стрілки з геттером за допомогою Object.definePropertyтехніки.

{
  ...
  Object.defineProperty(your_obj, 'status', { 
     get : () => this.xhr.status 
  });
  ...
}

Див. Згадки про object initialization техніку (вона ж get NAME() {...}) протиdefineProperty техніки (вона ж get : ()=>{}) . Існує принаймні одна суттєва різниця, використанняdefinePropertyвимагає, щоб змінні вже існували:

Визначення геттера для існуючих об'єктів

тобто Object.definePropertyви повинні переконатися, що your_obj(у моєму прикладі) існує та зберігається у змінній (тоді як за допомогою a object-initializationви можете повернути об’єкт-літерал в ініціалізації об’єкта:) {..., get(){ }, ... }. Детальніше про це Object.defineProperty, тут

Object.defineProperty(...)схоже, що підтримка браузера порівнянна із get NAME(){...}синтаксисом; сучасні браузери, IE 9.


10
Розумно, але в підсумку це набагато багатослівніше, ніж просто:get status() { return this.xhr.status; }
devuxer

2
@devuxer Я згоден, що це занадто багатослівно. Але щоб бути зрозумілим, ви this повинні бути об’єктом, в якому get status() { ... }визначається ваше . Але я this міг би бути чимось іншим, через лексичні відмінності між прив'язками, так?
The Red Pea

2
Погодьтеся ... хоча на практиці я не стикався з випадком, коли thisне те, що я хочу, у access access. ( thisЗдається, переваги прив'язки функцій зі стрілками вступають у дію при передачі функцій навколо, як у випадку з обробниками подій та зворотними
викликами

3
Я згоден, я часто використовую жирну стрілку + лексичні прив'язки ()=>{}для зворотних дзвінків, які я передаю на Обіцянку , наприклад $http(...).then((promise_result)=> this...})). Якщо я не використовую жирову стрілку, thisбуде представляти глобальний Windowоб'єкт; не дуже корисно. Але я рідко (ніколи?) Використовував ()=>{}як функцію "get accessor", як ти кажеш ... принаймні thisвсередині get()буде представляти об'єкт, для якого get()визначено (що вже є більш корисним, ніж Window; тому немає необхідності використовувати функція жирової стрілки!)
Червоний горошок
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.