ES6 getter / setter với chức năng mũi tên


100

Tôi đang sử dụng babel6 và cho dự án thú cưng của mình, tôi đang tạo một trình bao bọc cho XMLHttpRequest, cho các phương pháp tôi có thể sử dụng:

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

nhưng đối với thuộc tính, hàm mũi tên không hoạt động

những công việc này:

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

nhưng tôi không thể sử dụng

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

Đây là cố ý?


Bạn không cần dấu ngoặc nhọn hoặc giá trị trả về; bạn chỉ có thể nói (method, url, something) => this.xhr.open(method. url, something).

getlà một phần của đối tượng theo nghĩa đen hoặc định nghĩa lớp, phép gán biến thì không. Bạn nghĩ tại sao chúng nên hoạt động giống nhau?
Bergi

1
status => this.xhr.status( get status() => this.xhr.statuscú pháp c # 7) hoặc có thể thực sự sẽ là một đường cú pháp tuyệt vời để có thể đọc được nhưng Javascript không phải là chữ viết của Typecript (chưa?) hỗ trợ nó
Charles HETIER

Câu trả lời:


109

Theo ngữ pháp ES2015, một thuộc tính trên một đối tượng theo nghĩa đen chỉ có thể là một trong bốn điều sau:

Định nghĩa :

  • Mã định danh
  • Thuộc : tínhName AssignmentExpression
  • MethodDefinition

Loại duy nhất trong số này cho phép dẫn đầu getMethodDefinition :

Phương pháp Định nghĩa :

  • PropertyName ( StrictFormalParameters ) { FunctionBody }
  • GeneratorMethod
  • get Thuộc ( ) { tínhName Chức năngBody }
  • set PropertyName ( PropertySetParameterList ) { FunctionBody }

Như bạn có thể thấy, getbiểu mẫu tuân theo một ngữ pháp rất hạn chế mà phải có biểu mẫu

get NAME () { BODY }

Ngữ pháp không cho phép các chức năng của biểu mẫu get NAME = ....


Cảm ơn sự giúp đỡ của bạn, tôi chấp nhận câu trả lời của bạn. Bạn có biết nơi nó được định nghĩa rằng getter / setter không thể được sử dụng với một bài tập không? Chỉ tò mò.
Gabor Dolla

@GaborDolla Đã chỉnh sửa để tham chiếu đến ngữ pháp theo nghĩa đen của đối tượng trong đặc tả ECMAScript.
apsillers

35

Câu trả lời được chấp nhận là tuyệt vời. Tốt nhất là bạn nên sử dụng cú pháp hàm bình thường thay vì "cú pháp hàm mũi tên".

Nhưng có thể bạn thực sự thích các chức năng mũi tên; có thể bạn sử dụng hàm mũi tên vì một lý do khác mà cú pháp hàm thông thường không thể thay thế ; bạn có thể cần một giải pháp khác.

Ví dụ, tôi nhận thấy việc sử dụng OP this, bạn có thể muốn liên kết từ thisvựng; hay còn gọi là "không ràng buộc của điều này" ), và các hàm mũi tên rất tốt cho liên kết từ vựng đó.

Bạn vẫn có thể sử dụng hàm mũi tên với getter thông qua Object.definePropertykỹ thuật này.

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

Xem các đề cập về object initializationkỹ thuật (hay còn gọi là get NAME() {...}) so với definePropertykỹ thuật (còn gọi là get : ()=>{}) . Có ít nhất một sự khác biệt đáng kể, việc sử dụng definePropertyyêu cầu các biến đã tồn tại:

Xác định một getter trên các đối tượng hiện có

tức là với Object.definePropertybạn phải đảm bảo rằng your_obj(trong ví dụ của tôi) tồn tại và được lưu vào một biến (trong khi với một, object-initializationbạn có thể trả về một đối tượng-chữ trong lần khởi tạo đối tượng của bạn {..., get(){ }, ... }:). Thông tin thêm về Object.definePropertycụ thể, tại đây

Object.defineProperty(...)dường như có hỗ trợ trình duyệt tương đương với get NAME(){...}cú pháp; trình duyệt hiện đại, IE 9.


10
Thông minh, nhưng nó cuối cùng nhiều tiết hơn chỉ:get status() { return this.xhr.status; }
devuxer

2
@devuxer Tôi đồng ý rằng nó quá dài dòng. Nhưng chỉ cần nói rõ, của bạn this phải là đối tượng mà bạn get status() { ... }được định nghĩa. Nhưng của tôi this có thể là một cái gì đó khác, do sự khác biệt ràng buộc từ vựng, phải không?
The Red Pea

2
Đồng ý ... mặc dù trong thực tế, tôi đã không gặp phải trường hợp thiskhông phải là những gì tôi muốn trong một get accessor. (Các thislợi ích ràng buộc của chức năng mũi tên dường như đi vào chơi khi đi qua các chức năng xung quanh, như với xử lý sự kiện và callbacks.)
devuxer

3
Tôi đồng ý, tôi thường xuyên sử dụng các liên kết từ vựng + mũi tên béo ()=>{}cho các lệnh gọi lại mà tôi chuyển cho một Lời hứa , chẳng hạn như $http(...).then((promise_result)=> this...})). Nếu tôi không sử dụng fat-arrow, thissẽ đại diện cho Windowđối tượng toàn cục ; không hữu ích lắm. Nhưng tôi hiếm khi (chưa bao giờ?) Sử dụng ()=>{}làm hàm cho "get accessor" như bạn nói ... ít nhất thisbên trong của get()sẽ đại diện cho đối tượng get()được xác định trên đó (vốn đã hữu ích hơn Window; vì vậy không cần sử dụng một hàm mũi tên béo!)
The Red Pea
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.