Hàm * * trong JavaScript là gì?


243

Trong này trang Tôi tìm thấy một hàm JavaScript mới loại:

// NOTE: "function*" is not supported yet in Firefox.
// Remove the asterisk in order for this code to work in Firefox 13 

function* fibonacci() { // !!! this is the interesting line !!!
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}

Tôi đã biết những gì yield, let[?,?]=[?,?]làm , nhưng không biết ý function*nghĩa của nó là gì. Nó là gì?

PS đừng bận tâm dùng thử Google, không thể tìm kiếm biểu thức bằng dấu hoa thị ( chúng được sử dụng làm trình giữ chỗ ).


4
Nhận xét trong ví dụ này khá cũ, function*cú pháp được hỗ trợ trong Firefox kể từ v26: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ trộm *. Các phiên bản cũ hơn đã sử dụng một cú pháp khác nhau.
Nickolay

39
Về Google, chỉ cần tìm kiếm "ngôi sao chức năng" hoặc "dấu hoa thị chức năng". Đó là cách tôi tìm thấy câu hỏi này;).
phân tích

2
Có vẻ như *đã bị xóa khỏi liên kết từ @Nickolay. Đây là một liên kết trực tiếp đến function*tại MDN . Chắc chắn, hỗ trợ "cơ bản" kể từ v26 .
ruffin

Một liên kết MDN (trong đó, bằng cách này, tôi tìm thấy trên trang MDN liên kết bởi OP) : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
BlueRaja - Danny Pflughoeft

Một liên kết MDN hữu ích khác: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ Kẻ *
Logan

Câu trả lời:


199

Đó là một chức năng Máy phát điện .

Máy phát điện là các chức năng có thể được thoát ra và sau đó được nhập lại. Bối cảnh của họ (ràng buộc biến) sẽ được lưu trên các lối vào lại.

Gọi một hàm tạo không thực hiện ngay phần thân của nó; thay vào đó, một đối tượng lặp cho hàm được trả về. Khi next()phương thức của trình lặp được gọi, phần thân của hàm trình tạo được thực thi cho đến khi yieldbiểu thức đầu tiên , xác định giá trị được trả về từ trình vòng lặp hoặc, với yield*, ủy nhiệm cho một hàm trình tạo khác.


Ghi chú lịch sử:

Đó là một cú pháp được đề xuất cho EcmaScript.next.

Dave Herman của Mozilla đã nói về EcmaScript.next . Lúc 30:15 , ông nói về máy phát điện.

Trước đó, ông giải thích cách Mozilla thực hiện thử nghiệm các thay đổi ngôn ngữ được đề xuất để giúp chỉ đạo ủy ban. Dave hợp tác chặt chẽ với Brendan Eich, CTO của Mozilla (tôi nghĩ) và nhà thiết kế JavaScript gốc.

Bạn có thể tìm thêm chi tiết trên wiki nhóm làm việc EcmaScript: http://wiki.ecmascript.org/doku.php?id=harmony:generators

Nhóm làm việc (TC-39) có thỏa thuận chung rằng EcmaScript.next nên có một số loại đề xuất trình lặp, nhưng đây không phải là cuối cùng.

Bạn không nên dựa vào điều này hiển thị mà không thay đổi trong phiên bản tiếp theo của ngôn ngữ và ngay cả khi nó không thay đổi, có thể nó sẽ không hiển thị rộng rãi trong các trình duyệt khác trong một thời gian.

Tổng quat

Các coroutines hạng nhất, được biểu diễn dưới dạng các đối tượng đóng gói các bối cảnh thực thi bị treo (tức là kích hoạt chức năng). Nghệ thuật ưu tiên: Python, Icon, Lua, Scheme, Smalltalk.

Ví dụ

Chuỗi số vô hạn của các số Fibonacci (các hành vi bất chấp khoảng 2 53 ):

function* fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}

Máy phát điện có thể được lặp đi lặp lại trong các vòng lặp:

for (n of fibonacci()) {
    // truncate the sequence at 1000
    if (n > 1000)
        break;
    print(n);
}

Máy phát điện là các vòng lặp:

let seq = fibonacci();
print(seq.next()); // 1
print(seq.next()); // 2
print(seq.next()); // 3
print(seq.next()); // 5
print(seq.next()); // 8

7
Theo dõi: một vòng lặp for không có tham số ( for(;;)) làm gì? Tại sao sử dụng nó trong bối cảnh này?
Fergie

13
@Fergie, for(;;)cũng giống như while (true). Nó được sử dụng trong bối cảnh này vì chuỗi Fibonacci là một chuỗi không giới hạn.
Mike Samuel

5
Nghệ thuật ưu tiên: năng suất C #?
Dave Van den Eynde

3
@DaveVandenEynde, nghệ thuật ưu tiên trước: Sản lượng Python. Ưu tiên nghệ thuật trước: CLU và Biểu tượng.
Mike Samuel

52

Đây là một hàm tạo - và nó đã nói như vậy trong trang bạn trích dẫn, trong bình luận bạn đã thay thế bằng "đây là dòng thú vị" ...

Về cơ bản, đó là một cách để xác định các chuỗi theo chương trình để chúng có thể được truyền xung quanh và các phần tử được truy cập bởi chỉ mục mà không phải tính toán toàn bộ chuỗi (có thể có kích thước vô hạn) trước đó.


10
"được truy cập bởi chỉ mục mà không phải tính toán toàn bộ chuỗi" có thể là lời giải thích hữu ích nhất về các máy phát điện mà tôi đã gặp cho đến nay. Tôi có thể thấy việc sử dụng điều này trong một ứng dụng, so với trước đây chỉ là hiểu nó về mặt lý thuyết.
wes

11

Các function*loại trông giống như nó hoạt động như một chức năng máy phát điện cho các quá trình có thể được lặp. C # có một tính năng như thế này bằng cách sử dụng "lợi nhuận", xem 1xem 2

Về cơ bản, điều này trả về từng giá trị từng cái một cho bất cứ điều gì đang lặp lại hàm này, đó là lý do tại sao trường hợp sử dụng của chúng hiển thị nó trong một vòng lặp kiểu foreach.

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.