“ function *” ใน JavaScript คืออะไร


243

ในหน้านี้ฉันพบประเภทฟังก์ชั่น JavaScript ใหม่:

// 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;
    }
}

ผมรู้อยู่แล้วว่าสิ่งที่yield, letและ[?,?]=[?,?]ทำแต่ไม่มีความคิดว่าสิ่งที่function*มีขึ้นเพื่อเป็น มันคืออะไร?

ป.ล. ไม่ต้องทดลองใช้ Google เป็นไปไม่ได้ที่จะค้นหานิพจน์ด้วยเครื่องหมายดอกจัน ( ใช้แทนตัวยึด )


4
ความคิดเห็นในตัวอย่างค่อนข้างเก่าตอนนี้function*รองรับไวยากรณ์ใน Firefox ตั้งแต่ v26: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ ...... * เวอร์ชันที่เก่ากว่าใช้ไวยากรณ์ที่แตกต่าง
Nickolay

39
เกี่ยวกับ Google เพียงค้นหา "function star" หรือ "function asterisk" นั่นเป็นวิธีที่ฉันพบคำถามนี้;)
trysis

2
ดูเหมือนว่า*จะถูกถอดออกจากลิงก์จาก @Nickolay นี่คือการเชื่อมโยงโดยตรงกับfunction*ที่ MDN พอแน่ใจว่า "พื้นฐาน" การสนับสนุนตั้งแต่ V26
ruffin

ลิงค์ MDN อื่น(ซึ่งโดยวิธีการที่ฉันพบในหน้า MDN เชื่อมโยงโดย OP) : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
......

ลิงก์ MDN อื่นที่มีประโยชน์: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ ...... *
Logan

คำตอบ:


199

มันเป็นเครื่องปั่นไฟฟังก์ชั่น

เครื่องกำเนิดไฟฟ้าเป็นฟังก์ชั่นที่สามารถออกและเข้ามาใหม่ได้ในภายหลัง บริบทของพวกเขา (การผูกตัวแปร) จะถูกบันทึกไว้ในการเข้า - ออกใหม่

การเรียกฟังก์ชันตัวสร้างไม่ได้เรียกใช้งานตัวมันทันที วัตถุตัววนซ้ำสำหรับฟังก์ชันจะถูกส่งคืนแทน เมื่อมีnext()การเรียกใช้เมธอดiterator ฟังก์ชันของตัวกำเนิดจะถูกดำเนินการจนกระทั่งyieldนิพจน์แรกซึ่งระบุค่าที่จะส่งคืนจากตัววนซ้ำหรือด้วยyield*ตัวแทนจะไปยังฟังก์ชันตัวสร้างอื่น


บันทึกประวัติศาสตร์:

EcmaScript.nextมันเป็นไวยากรณ์ที่เสนอ

เดฟเฮอร์แมนของ Mozilla ให้พูดคุยเกี่ยวกับEcmaScript.next เวลา30:15 น.เขาพูดเกี่ยวกับเครื่องกำเนิดไฟฟ้า

ก่อนหน้านี้เขาอธิบายว่า Mozilla ได้ทดลองใช้การเปลี่ยนแปลงภาษาที่เสนอเพื่อช่วยคัดท้ายคณะกรรมการอย่างไร Dave ทำงานใกล้ชิดกับ Brendan Eich, CTO ของ Mozilla (ฉันคิดว่า) และผู้ออกแบบจาวาสคริปต์ดั้งเดิม

คุณสามารถค้นหารายละเอียดเพิ่มเติมเกี่ยวกับวิกิ EcmaScript ที่ทำงานในกลุ่ม: http://wiki.ecmascript.org/doku.php?id=harmony:generators

คณะทำงาน (TC-39) มีข้อตกลงทั่วไปที่ EcmaScript.next ควรมีข้อเสนอของตัวสร้างตัววนซ้ำบางส่วน แต่นี่ไม่ใช่ขั้นสุดท้าย

คุณไม่ควรพึ่งพาการแสดงนี้โดยไม่มีการเปลี่ยนแปลงในภาษาเวอร์ชันถัดไปและแม้ว่ามันจะไม่เปลี่ยนแปลง แต่ก็อาจจะไม่ปรากฏในเบราว์เซอร์อื่น ๆ สักพัก

ภาพรวม

coroutines ชั้นหนึ่งแสดงเป็นวัตถุที่ห่อหุ้มบริบทการดำเนินการระงับ (เช่นการเปิดใช้งานฟังก์ชั่น) ศิลปะก่อนหน้า: Python, ไอคอน, Lua, Scheme, Smalltalk

ตัวอย่าง

ลำดับ "ไม่มีที่สิ้นสุด" ของหมายเลขฟีโบนักชี (แม้จะมีพฤติกรรมประมาณ 2 53 ):

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

เครื่องกำเนิดไฟฟ้าสามารถวนซ้ำในลูป:

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

เครื่องกำเนิดไฟฟ้าเป็นตัววนซ้ำ:

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

7
การติดตาม: การวนซ้ำที่ไม่มีพารามิเตอร์ ( for(;;)) ทำอะไรได้บ้าง ทำไมจึงต้องใช้ในบริบทนี้
เฟอร์กี

13
@Fergie, เป็นเช่นเดียวกับfor(;;) while (true)มันถูกใช้ในบริบทนี้เนื่องจากลำดับฟีโบนักชีเป็นลำดับที่ไม่มีขอบเขต
Mike Samuel

5
ศิลปะก่อนหน้า: ผลผลิต C #?
Dave Van den Eynde

3
@DaveVandenEynde ศิลปะก่อนหน้านี้: ผลผลิต Python ก่อนหน้าศิลปะก่อนหน้า: CLU และไอคอน
Mike Samuel

52

มันเป็นฟังก์ชั่นเครื่องกำเนิดไฟฟ้า - และมันก็บอกอย่างนั้นในหน้าเว็บที่คุณอ้างถึงในความคิดเห็นที่คุณแทนที่ด้วย "นี่คือสายที่น่าสนใจ" ...

โดยทั่วไปมันเป็นวิธีการระบุลำดับโดยทางโปรแกรมเพื่อให้พวกเขาสามารถผ่านไปรอบ ๆ และองค์ประกอบที่เข้าถึงได้โดยดัชนีโดยไม่ต้องคำนวณลำดับทั้งหมด


10
"เข้าถึงโดยดัชนีโดยไม่ต้องคำนวณทั้งลำดับ" อาจเป็นคำอธิบายที่มีประโยชน์ที่สุดเกี่ยวกับเครื่องกำเนิดไฟฟ้าที่ฉันเคยพบมาก่อน ฉันสามารถเห็นการใช้สิ่งนี้ในแอปก่อนหน้านี้เพียงแค่เข้าใจในทางทฤษฎี
เวส

11

function*ประเภทดูเหมือนว่ามันทำหน้าที่เป็นฟังก์ชั่นเครื่องกำเนิดไฟฟ้าสำหรับกระบวนการที่สามารถซ้ำ C # มีคุณสมบัติเช่นนี้โดยใช้ "อัตราผลตอบแทนคืน" ดู 1และดู 2

โดยพื้นฐานแล้วสิ่งนี้จะคืนค่าแต่ละค่าทีละหนึ่งไปยังสิ่งใดก็ตามที่ทำซ้ำฟังก์ชันนี้ซึ่งเป็นสาเหตุที่เคสการใช้งานของพวกเขาแสดงในลูปสไตล์ foreach

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.