Pengambil / penyetel ES6 dengan fungsi panah

106

Saya menggunakan babel6 dan untuk proyek hewan peliharaan saya, saya membuat pembungkus untuk XMLHttpRequest, untuk metode yang dapat saya gunakan:

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

tetapi untuk fungsi panah properti tidak berfungsi

ini bekerja:

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

tapi saya tidak bisa menggunakan

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

Apakah ini disengaja?

Gabor Dolla
sumber
Anda tidak perlu tanda kurung kurawal atau pengembalian; Anda bisa mengatakannya (method, url, something) => this.xhr.open(method. url, something).
getadalah bagian dari literal objek atau definisi kelas, tugas variabel bukan. Menurut Anda mengapa mereka harus bekerja sama?
Bergi
2
status => this.xhr.status(c # 7 sintaks) atau mungkin get status() => this.xhr.statusmemang akan menjadi gula sintaksis yang bagus untuk keterbacaan tetapi Javascript tidak Typecript (belum?) mendukungnya
Charles HETIER

Jawaban:

113

Menurut tata bahasa ES2015, properti pada literal objek hanya dapat berupa satu dari empat hal:

PropertyDefinition :

  • IdentifierReference
  • PropertyName : AssignmentExpression
  • MethodDefinition

Satu-satunya jenis yang memungkinkan pengarahanget adalah MethodDefinition :

Metode Definisi :

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

Seperti yang Anda lihat, getformulir mengikuti tata bahasa yang sangat terbatas yang harus ada di formulir

get NAME () { BODY }

Tata bahasa tidak mengizinkan fungsi formulir get NAME = ....

apsillers
sumber
Terima kasih atas bantuan Anda, saya menerima jawaban Anda. Apakah Anda tahu di mana didefinisikan bahwa pengambil / penyetel tidak dapat digunakan dengan tugas? Hanya penasaran.
Gabor Dolla
@GaborDolla Diedit untuk merujuk ke tata bahasa literal objek dalam spesifikasi ECMAScript.
apsillers
39

Jawaban yang diterima bagus. Ini yang terbaik jika Anda ingin menggunakan sintaks fungsi normal daripada "sintaks fungsi panah" yang ringkas.

Tapi mungkin Anda sangat menyukai fungsi panah; mungkin Anda menggunakan fungsi panah untuk alasan lain yang tidak dapat diganti oleh sintaks fungsi normal ; Anda mungkin membutuhkan solusi yang berbeda.

Misalnya, saya perhatikan penggunaan OP this, Anda mungkin ingin mengikat thissecara leksikal; alias "tidak mengikat ini" ), dan fungsi panah baik untuk pengikatan leksikal itu.

Anda masih bisa menggunakan fungsi panah dengan getter melalui Object.definePropertyteknik ini.

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

Lihat menyebutkan object initializationteknik (alias get NAME() {...}) vs definePropertyteknik (alias get : ()=>{}) . Setidaknya ada satu perbedaan signifikan, menggunakan definePropertymembutuhkan variabel yang sudah ada:

Mendefinisikan pengambil pada objek yang ada

yaitu dengan Object.definePropertyAnda harus memastikan bahwa your_obj(dalam contoh saya) ada dan disimpan ke dalam variabel (sedangkan dengan object-initializationAnda dapat mengembalikan objek-literal dalam inisialisasi objek Anda :) {..., get(){ }, ... }. Info lebih lanjut Object.definePropertysecara khusus, di sini

Object.defineProperty(...)tampaknya memiliki dukungan browser yang sebanding dengan get NAME(){...}sintaksis; browser modern, IE 9.

Kacang Merah
sumber
11
Cerdas, tetapi pada akhirnya jauh lebih bertele-tele daripada hanya:get status() { return this.xhr.status; }
devuxer
2
@ Devuxer Saya setuju itu terlalu bertele-tele. Namun untuk memperjelas, Anda this harus menjadi objek yang Anda get status() { ... }definisikan. Tapi saya this bisa menjadi sesuatu yang lain, karena perbedaan ikatan leksikal, bukan?
The Red Pea
2
Setuju ... meskipun dalam praktiknya, saya belum mengalami kasus di mana thisbukan yang saya inginkan dalam mendapatkan aksesor. ( thisManfaat yang mengikat dari fungsi panah tampaknya ikut bermain ketika meneruskan fungsi, seperti halnya dengan penangan acara dan panggilan balik.)
devuxer
3
Saya setuju, saya sering menggunakan panah lemak + binding leksikal ()=>{} untuk callback yang saya berikan ke Promise , seperti $http(...).then((promise_result)=> this...})). Jika saya tidak menggunakan panah lemak, thisakan mewakili Windowobjek global ; tidak terlalu berguna. Tapi saya jarang (tidak pernah?) Telah menggunakan ()=>{}fungsi untuk "get accessor" seperti yang Anda katakan ... setidaknya thisdi dalam get()akan mewakili objek yang get()didefinisikan (yang sudah lebih berguna daripada Window; jadi tidak perlu menggunakan fungsi panah lemak!)
The Red Pea
1
The definePropertyPendekatan berguna dalam loop. Saat ini saya hanya menggunakannya untuk mengekspos beberapa properti objek chiled dari yang mengandung.
Edurne Pascual