ฉันจะอธิบายสิ่งนี้อย่างไร:
function *(next) {}
ด้วยลูกศร ฉันลองชุดค่าผสมทั้งหมดที่ฉันสามารถนึกได้และไม่พบเอกสารใด ๆ
(ปัจจุบันใช้โหนด v0.11.14)
param*=>{ }
จะทำอะไร?
function(){}
ไม่ว่าไม่ทำเช่นเดียวกัน()=>{}
?
ฉันจะอธิบายสิ่งนี้อย่างไร:
function *(next) {}
ด้วยลูกศร ฉันลองชุดค่าผสมทั้งหมดที่ฉันสามารถนึกได้และไม่พบเอกสารใด ๆ
(ปัจจุบันใช้โหนด v0.11.14)
param*=>{ }
จะทำอะไร?
function(){}
ไม่ว่าไม่ทำเช่นเดียวกัน()=>{}
?
คำตอบ:
ฉันสามารถใช้ไวยากรณ์ฟังก์ชั่นลูกศรของ ES6 กับเครื่องกำเนิดไฟฟ้าได้หรือไม่?
คุณทำไม่ได้ ขอโทษ
ตามMDN
function*
คำสั่ง (function
ตามคำหลักด้วยเครื่องหมายดอกจัน) กำหนดฟังก์ชั่นเครื่องกำเนิดไฟฟ้า
จากเอกสารข้อมูลจำเพาะ (ความสำคัญของฉัน):
ฟังก์ชั่นไวยากรณ์จะขยายเพื่อเพิ่มตัวเลือก
*
โทเค็น:
FunctionDeclaration: "function" "*"? Identifier "(" FormalParameterList? ")"
"{" FunctionBody "}"
.prototype
ตัวอย่าง) และมักจะมีหนึ่ง liners ในขณะที่เครื่องกำเนิดไฟฟ้าค่อนข้างตรงกันข้าม
this
และต้องเขียนlet self = this
แฮ็กเพื่อเข้าถึงภายในตัวสร้าง ไวยากรณ์ขอบเขต + ลูกศรศัพท์น่าจะดี โชคร้าย แต่ไม่ใช่จุดจบของโลก
function
คำหลักเพื่อเป็น 'ส่วนที่ไม่ดี' ของภาษา มีเหตุผลที่ดีในการทำเช่นนี้ สำหรับคนเหล่านี้การขาดเครื่องกำเนิดลูกศรเป็นสิ่งที่ไม่สอดคล้องกันที่น่ารำคาญ
ประการแรกฟังก์ชั่นลูกศร ทั้งหมด() => {}
ไม่ได้ทำขึ้นเพื่อแทนที่ฟังก์ชั่นอินไลน์function(){}
และมีความแตกต่างกัน ฟังก์ชั่นอินไลน์เป็นเพียงฟังก์ชั่นดังนั้นคำถามคือความแตกต่างระหว่างฟังก์ชั่นลูกศรและฟังก์ชั่นอินไลน์คืออะไร
ฟังก์ชั่นการแสดงออกศร (หรือเรียกว่าฟังก์ชั่นลูกศร) มีไวยากรณ์สั้นเมื่อเทียบกับการแสดงออกและฟังก์ชั่นไม่ได้ผูกของตัวเอง
this
,arguments
,super
หรือnew.target
) ฟังก์ชั่นลูกศรไม่ระบุชื่อเสมอ
ดูรายละเอียดเพิ่มเติมได้ที่นี่
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
การใช้คำหลักผลตอบแทน
ผลผลิตคำหลักอาจไม่สามารถใช้ในร่างกายของฟังก์ชั่นของลูกศร (ยกเว้นเมื่อได้รับอนุญาตภายในฟังก์ชั่นเพิ่มเติมที่ซ้อนกันอยู่ภายใน) ดังนั้นฟังก์ชั่นลูกศรจึงไม่สามารถใช้เป็นเครื่องกำเนิดไฟฟ้าได้
โปรดทราบว่าเครื่องกำเนิดไฟฟ้าที่ไม่มีyield
ความหมาย
http://tc39wiki.calculist.org/es6/arrow-functions/
ฟังก์ชั่นลูกศรผูกคำ
this
ศัพท์ผูกreturn
ในกรณีที่ร่างกายบล็อกดังนั้นมันกลับมาจากฟังก์ชั่นลูกศรล้อมรอบทันทีและป้องกันbreak
และcontinue
จากการอ้างอิงคำสั่งนอกฟังก์ชั่นลูกศรล้อมรอบทันทีตัวบ่งชี้การแสดงออกหลัก
arguments
อาจไม่สามารถใช้ในร่างกายของฟังก์ชั่นของลูกศร (ไม่ว่าจะแสดงออกหรือรูปแบบบล็อก)ในทำนองเดียวกัน
yield
อาจไม่สามารถใช้ในร่างกายของฟังก์ชั่นลูกศร ลูกศรไม่สามารถเป็นเครื่องกำเนิดไฟฟ้าได้และเราไม่ต้องการความต่อเนื่องในเชิงลึก
ผลตอบแทนในฟังก์ชั่นลูกศรจะทำให้เกิดข้อผิดพลาดทางความหมาย: http://www.ecma-international.org/
ในที่สุดเหตุผลก็คือความซับซ้อนในการใช้ ECMA6 C # จะไม่ปล่อยให้เรื่องนี้เป็นอย่างดีสำหรับค่อนข้างคล้ายเหตุผล
()=>{}
จะช่วยได้มากทำความเข้าใจกับความแตกต่างจากฟังก์ชั่นในบรรทัดและทำไมข้อ จำกัด มีสำหรับเครื่องกำเนิดไฟฟ้า
*() => { yield bla; }
ไม่โอเค แต่async () => { await bla; }
เป็น ...
นอกจากนี้ในการอภิปรายในesdiscuss.orgและEcma TC39 คณะกรรมการ ES6 บันทึกการประชุมจากพฤศจิกายน 2013ดังกล่าวข้างต้นกำเนิดลูกศรถูกเยือนในสองกันยายน 2016 ES7 ประชุม[1] [2] หลังจากการอภิปรายเกี่ยวกับข้อดีข้อเสียของไวยากรณ์ต่าง ๆ (ส่วนใหญ่=*>
และ=>*
) และการขาดการให้เหตุผลและการใช้กรณีสำหรับคุณลักษณะนี้พวกเขามาถึงข้อสรุปที่:
- มีความสนใจจากคณะกรรมการบ้าง แต่กังวลว่าฟีเจอร์นี้จะไม่ดึงน้ำหนักเพื่อเพิ่มไวยากรณ์ใหม่
- วางแผนที่จะกลับมาเยี่ยมชมในวันที่ 3 เพื่อดูว่าเราจะ
=>*
ไปถึงขั้นที่ 0 เป็นอย่างน้อยหรือไม่ซึ่งเป็นส่วนหนึ่งของข้อเสนอการทำซ้ำแบบซิงโครไนซ์ของ Domenic Denicola
ข้อเสนอสำหรับลูกศรกำเนิดถูกย้ายไปยังด่าน1โดยเบรนแดนไอชและโดเมนิกเดนิโคลาเป็นผู้ชนะ การทำซ้ำแบบอะซิงโครนัสที่กล่าวถึงข้างต้นเสร็จสิ้นและนำไปใช้ในปี 2018
ในเดือนตุลาคมปี 2019 มีการซื้อคืนอย่างเป็นทางการโดย Sergey Rubanovปรากฏขึ้นพร้อมกับการอภิปรายเพิ่มเติมเกี่ยวกับไวยากรณ์และรายละเอียดอื่น ๆ
ฉันยังมีคำถามเดียวกันและมาที่นี่ หลังจากอ่านโพสต์และความคิดเห็นฉันรู้สึกว่าการใช้เครื่องกำเนิดไฟฟ้าในฟังก์ชั่นลูกศรดูเหมือนจะคลุมเครือ:
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
นี่คือสิ่งที่อาจเป็นเหตุผลใหญ่ที่พวกเขาไม่ได้ใช้เครื่องกำเนิดไฟฟ้าที่เกี่ยวข้องกับฟังก์ชั่นลูกศร
แต่ถ้าฉันเป็นหนึ่งในพวกเขาฉันอาจคิดแบบนี้:
const generator = gen param => ... // hmm, gen indicates a generator
const generator = gen () => ... // ^^
นี่รู้สึกเหมือนกับว่าเรามีฟังก์ชั่นแบบอะซิงโครนัส:
const asyncFunction = async () => ... // pretty cool
เพราะด้วยฟังก์ชั่นปกติมีคำหลักasyncอยู่ดังนั้นฟังก์ชั่นลูกศรจึงใช้มัน - async () =>
ดูเหมือนจะเป็นไปasync function()
ได้
แต่ไม่มีคำหลักที่ชอบgen
หรือgenerator
และฟังก์ชั่นลูกศรไม่ได้ใช้มัน
สรุป:
แม้ว่าพวกเขาต้องการที่จะใช้เครื่องกำเนิดไฟฟ้าในฟังก์ชั่นลูกศรฉันคิดว่าพวกเขาต้องคิดใหม่เกี่ยวกับไวยากรณ์ของเครื่องกำเนิดไฟฟ้าใน core js:
generator function myfunc() {}
// rather than
function* myfunc() {} // or, function *myfunc() {}
และนี่จะเป็นความผิดพลาดครั้งใหญ่ ดังนั้นการรักษาฟังก์ชั่นลูกศรออกจากเครื่องกำเนิดไฟฟ้าก็ค่อนข้างดี
กำลังติดตามความคิดเห็น @Bergi :
ไม่ได้ฟังก์ชั่น Arrow นั้นควรจะมีน้ำหนักเบา (และไม่มีตัวอย่างต้นแบบ) และมักจะเป็น liners หนึ่งตัวในขณะที่เครื่องกำเนิดไฟฟ้าค่อนข้างตรงกันข้าม
ฉันจะบอกว่าจุดประสงค์ของตัวสร้างที่จะใช้คือrun-stop-runและดังนั้นฉันไม่คิดว่าเราจำเป็นต้องใส่ใจกับต้นแบบ, คำศัพท์นี้เป็นต้น
() ~> { yield 'a'; yield 'b'; }
อาจจะพิจารณาตัวเลือกที่แปลกใหม่ด้วยเช่น พูดตามตรงฉันแค่รักตัวหนอน
ฉันรู้ว่านี่มันช้ามาก แต่อีกสาเหตุที่เป็นไปได้คือไวยากรณ์ อาจจะ(*() => {})
ทำงาน แต่สิ่งที่เกี่ยวกับ(9 ** () => {})
? คือการที่ 9 ถึงพลังของฟังก์ชั่นที่ลูกศรกลับNaN
หรือจะเป็นครั้งที่ 9 กำเนิดลูกศรฟังก์ชั่นยังกลับมาNaN
? มันสามารถทำได้ด้วยไวยากรณ์ทางเลือกบางอย่างเช่น=>*
ที่กล่าวถึงโดยคำตอบอื่นที่นี่ แต่อาจมีความปรารถนาที่จะรักษาความมั่นคงของไวยากรณ์ฟังก์ชั่นเครื่องกำเนิด (เช่นfunction* () {}
และ{ *genMethod() {} }
) เมื่อมันถูกนำมาใช้ ไม่ใช่ข้อแก้ตัวที่มากเกินไป แต่เป็นเหตุผลสำหรับมัน
ตอนนี้คุณไม่สามารถ แต่ในอนาคตคุณอาจจะเป็นเพราะ TC39 ปล่อย ข้อเสนอการในเดือนตุลาคม 2562 ซึ่งอยู่ในขั้นตอนที่ 1
มีวิธีแก้ปัญหาที่ดีกับ redux-saga
import { call, all } from 'redux-saga/effects';
function* gen() {
yield all([].map(() => {
return call(....);
}));
}
function*
คำสั่ง (ฟังก์ชั่นคีย์เวิร์ดตามด้วยเครื่องหมายดอกจัน) กำหนดฟังก์ชั่นเครื่องกำเนิด"