Tôi có thể sử dụng cú pháp hàm mũi tên của ES6 với các trình tạo không? (ký hiệu mũi tên)


242

tức là làm thế nào để tôi thể hiện điều này:

function *(next) {}

với mũi tên. Tôi đã thử tất cả các kết hợp mà tôi có thể nghĩ ra và tôi không thể tìm thấy bất kỳ tài liệu nào về nó.

(hiện đang sử dụng nút v0.11,14)


5
Bạn không thể. Lấy làm tiếc. "Câu function*lệnh (từ khóa hàm theo sau dấu hoa thị) xác định hàm tạo."

2
Lưu ý rằng đã có một cuộc thảo luận hơi dài về chủ đề này tại esdiscuss.org .
voithos

4
Bạn mong đợi param*=>{ }làm gì?
CoderPi

4
Bạn có biết rằng đó function(){}không phải là làm như ()=>{}?
CoderPi

8
" có thực sự là máy phát ES6 tiến 2 bước và lùi 1 bước không? " - không, máy phát điện chỉ có thể bước về phía trước :-)
Bergi

Câu trả lời:


230

Tôi có thể sử dụng cú pháp hàm mũi tên của ES6 với các trình tạo không?

Bạn không thể. Lấy làm tiếc.

Theo MDN

Câu function*lệnh ( functiontừ khóa theo dấu hoa thị) xác định hàm tạo.

Từ một tài liệu đặc tả (nhấn mạnh của tôi):

Các chức năng cú pháp được mở rộng thêm một tùy chọn *mã thông báo:

FunctionDeclaration: "function" "*"? Identifier "(" FormalParameterList? ")" 
  "{" FunctionBody "}"

173
Cảm thấy như một lỗ hổng thiết kế với tôi.
Jonathon

23
@Jonathon: Không. Các chức năng mũi tên được cho là có trọng lượng nhẹ (và không có .prototypeví dụ) và thường là một lớp, trong khi máy phát điện thì hoàn toàn ngược lại.
Bergi

38
Tôi đã chạy qua một vài tình huống trong đó một trình tạo mà tôi đang chơi với quyền truy cập cần thiết vào trước đó thisvà phải viết bản let self = thishack để có quyền truy cập vào nó trong trình tạo. Phạm vi từ vựng + cú pháp mũi tên sẽ là tốt đẹp. Đáng tiếc, nhưng không chính xác là ngày tận thế.
dvlsg

3
Một số bối cảnh bổ sung xung quanh vấn đề này tại esdiscuss
Nick Tomlin

20
@Bergi lý do đằng sau các chức năng mũi tên phức tạp hơn thế nhiều. Nó không thực sự về sự ngắn gọn. Các hàm mũi tên không cần phải nhẹ - đúng là có một cú pháp thân câu lệnh đơn tùy chọn, nhưng vậy thì sao. Nhiều người sử dụng các mũi tên cho tất cả các định nghĩa hàm ngoại trừ các phương thức lớp và hạ cấp functiontừ khóa thành 'phần xấu' của ngôn ngữ. Có những lý do tốt để làm điều này. Đối với những người này, việc thiếu máy phát điện mũi tên là một sự mâu thuẫn khó chịu.
callum

130

Sự khác biệt giữa hàm Inline và hàm Arrow

Trước hết, các hàm Mũi tên () => {} không được tạo để thay thế các hàm Inline function(){}và chúng khác nhau. Hàm Inline đơn giản là Hàm, vì vậy câu hỏi đặt ra là sự khác biệt giữa Hàm mũi tên và Hàm Inline là gì.

Một biểu hiện mũi tên chức năng (còn gọi là mũi tên chức năng) có một cú pháp ngắn hơn so với biểu hiện chức năng và không ràng buộc riêng của mình this, arguments, super, hoặc new.target). Các chức năng mũi tên luôn ẩn danh.

Một số chi tiết nhanh hơn ở đây


Tại sao chức năng Mũi tên không thể được sử dụng làm máy phát điện

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Fifts/Arrow_fifts

Sử dụng từ khóa năng suất

Các năng suất từ khóa có thể không được sử dụng trong cơ thể một mũi tên chức năng của (trừ khi được phép trong phạm vi chức năng tiếp tục lồng bên trong nó). Do đó, các chức năng mũi tên không thể được sử dụng làm máy phát điện.

Lưu ý rằng máy phát điện không có yieldý nghĩa.


Tại sao hàm Arrow không thể sử dụng năng suất

http://tc39wiki.calculist.org/es6/arrow-fifts/

Các hàm mũi tên liên kết từ thisvựng, liên kết returntrong trường hợp Khối cơ thể để nó trả về từ hàm mũi tên kèm theo ngay lập tức, và loại trừ breakcontinuetừ các câu lệnh tham chiếu bên ngoài hàm mũi tên kèm theo ngay lập tức.

Các định danh biểu chính argumentscó thể không được sử dụng trong cơ thể một mũi tên chức năng của (xem biểu thức hoặc hình thức khối).

Tương tự như vậy, yieldcó thể không được sử dụng trong cơ thể của một mũi tên. Mũi tên không thể là máy phát điện và chúng tôi không muốn tiếp tục sâu.

Hiệu suất trong Hàm mũi tên sẽ gây ra lỗi ngữ nghĩa: http : //www.ecma-i quốc.org /

Cuối cùng, lý do là ở sự phức tạp sâu sắc trong việc thực hiện ECMA6. C # không cho phép điều này cũng vì lý do tương tự .


3
Tôi đã sử dụng một công cụ tìm kiếm và đăng thêm một Giải thích cho bạn
CoderPi

1
Tôi vẫn nghĩ rằng việc thêm giải thích về ()=>{}sẽ giúp ích rất nhiều, để hiểu sự khác biệt của nó so với chức năng nội tuyến và tại sao lại có giới hạn cho máy phát điện.
Vitaly-t

63
Tôi đang cố gắng tìm hiểu tại sao *() => { yield bla; }không ổn, nhưng async () => { await bla; }là ...
Lee Benson

7
@CodeiSir, Re " và chúng tôi không muốn tiếp tục sâu sắc ", lý do tệ hại.
Pacerier

9
Lập luận của bạn là theo chu kỳ. Bạn nói rằng các hàm mũi tên không thể là trình tạo vì chúng không thể có từ khóa năng suất trong đó. Nhưng họ không thể có từ khóa năng suất, bởi vì họ không thể là máy phát điện: "Mũi tên không thể là máy phát điện và chúng tôi không muốn tiếp tục sâu."
Thayne

35

Ngoài các cuộc thảo luận trên esdiscuss.orgghi chú cuộc họp ES6 của ủy ban Ecma TC39 từ tháng 11 năm 2013 đã đề cập ở trên, mũi tên của máy phát điện đã được xem xét lại trong hai cuộc họp ES7 tháng 9 năm 2016 [1] [2] . Sau một cuộc thảo luận về ưu và nhược điểm của các cú pháp khác nhau (chủ yếu =*>=>*) và thiếu các biện minh và trường hợp sử dụng cho tính năng này, họ đã đi đến kết luận rằng:

  • Có một số quan tâm từ ủy ban, nhưng lo ngại rằng tính năng này không làm tăng sức nặng của nó khi thêm một đoạn cú pháp mới
  • Lên kế hoạch xem lại vào Ngày 3 để xem liệu chúng tôi có thể =>*đến giai đoạn 0 ít nhất không, như là một phần của đề xuất lặp lại không đồng bộ của [Domenic Denicola]

Đề xuất cho mũi tên máy phát điện đã được chuyển sang Giai đoạn 1 với Brendan Eich và Domenic Denicola là những nhà vô địch. Lặp lại không đồng bộ được đề cập ở trên đã hoàn thành và thực hiện vào năm 2018.

Vào tháng 10 năm 2019, một repo chính thức của Serge Rubanov đã xuất hiện với nhiều cuộc thảo luận về cú pháp và các chi tiết khác.


8

Tôi cũng có câu hỏi tương tự và đến đây. Sau khi đọc các bài đăng và bình luận, tôi cảm thấy việc sử dụng trình tạo trong một hàm mũi tên dường như rất mơ hồ:

const generator = () => 2*3; // * implies multiplication
// so, this would be a confusing
const generator = () =>* something; // err, multiplying?
const generator = () =*> ... // err, ^^
const generator = ()*=> ... // err, *=3, still multiplying?
const generator=*()=> ... // err, ^^
const generator = *param => ... //err, "param" is not fixed word

Đây là lý do lớn có thể khiến họ không triển khai trình tạo liên quan đến chức năng mũi tên.


Nhưng, nếu tôi là một trong số họ, tôi có thể nghĩ như thế này:

const generator = gen param => ... // hmm, gen indicates a generator
const generator = gen () => ... // ^^

Cảm giác này giống như chúng ta có chức năng không đồng bộ:

const asyncFunction = async () => ... // pretty cool

Bởi vì, với chức năng bình thường, từ khóa async tồn tại, do đó, hàm mũi tên đang sử dụng nó - async () =>dường như có vẻ async function().

Nhưng, không có từ khóa như genhoặc generatorvà chức năng mũi tên than ôi không sử dụng nó.

Để kết luận:

Ngay cả khi họ muốn triển khai trình tạo trong hàm mũi tên, tôi nghĩ họ cần suy nghĩ lại về cú pháp của trình tạo trong lõi js:

generator function myfunc() {}
// rather than
function* myfunc() {} // or, function *myfunc() {}

Và đây sẽ là một sai lầm lớn. Vì vậy, giữ chức năng mũi tên ra khỏi máy phát điện, là khá mát mẻ.


Sau bình luận @Bergi :

Không. Các hàm mũi tên được cho là có trọng lượng nhẹ (và không có .prototype chẳng hạn) và thường là một lớp, trong khi các máy phát điện thì hoàn toàn ngược lại.

Tôi sẽ nói rằng mục đích của trình tạo để sử dụng là run-stop-run và vì vậy tôi không nghĩ rằng chúng ta cần quan tâm đến nguyên mẫu, từ vựng này, v.v.


2
Cũng có thể xem xét các lựa chọn kỳ lạ là tốt, như () ~> { yield 'a'; yield 'b'; }. Thành thật mà nói tôi chỉ yêu dấu ngã.
Gershom

@Gershom Đây là cách các ngôn ngữ lập trình như Perl hoàn toàn sai
Sapphire_Brick

2

Tôi biết rằng điều này là rất muộn, nhưng một lý do có thể khác có thể là cú pháp. có thể (*() => {})làm việc, nhưng những gì về (9 ** () => {})? Là 9 với sức mạnh của một chức năng mũi tên, trở lại NaN, hoặc là 9 lần một chức năng mũi tên máy phát điện, cũng trở lại NaN? Nó có thể được thực hiện với một số cú pháp thay thế, như =>*được đề cập bởi một câu trả lời khác ở đây, nhưng có thể có một mong muốn duy trì tính nhất quán của cú pháp hàm tạo (ví dụ function* () {}{ *genMethod() {} }) khi nó được thực hiện. Không quá nhiều lý do, nhưng một lý do cho nó.


1
: +1: cho các dấu sao đôi ... Anh chàng JS trường học cũ ở đây. Ai nói bạn không thể dạy cho một con chó già những mánh khóe mới: niềm vui:
Shanimal

Lý do duy nhất họ không làm điều đó là vì việc tạo trình phân tích cú pháp rất khó. Điều đó hoàn toàn có thể và không đòi hỏi sự thỏa hiệp trong cú pháp.
Jason McCarrell

@JasonMcCarrell Nếu họ quan tâm đủ về việc không làm cho trình phân tích cú pháp quá phức tạp, thì có lẽ Brendan Eich nên đưa Scheme vào trình duyệt.
Sapphire_Brick

1

Ngay bây giờ bạn không thể, nhưng trong tương lai bạn có thể là do đề xuất phát hành TC39 cho cùng vào tháng 10 năm 2019, trong giai đoạn 1.


-4

Có một cách giải quyết tốt với redux-saga

import { call, all } from 'redux-saga/effects';

function* gen() {
   yield all([].map(() => {
      return call(....);
   }));
}

4
Làm thế nào để chúng ta biết OP đang sử dụng Redux?
Maros
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.