ฟังก์ชัน CoffeeScript และตั้งชื่อ


10

ที่อื่นอาร์กิวเมนต์ได้เกิดขึ้นกับคำศัพท์ของฟังก์ชั่นที่มีชื่อใน CoffeeScript โดยเฉพาะใครบางคนที่พูดถึงสิ่งนี้:

 foo = ->
    console.log("bar")

เป็นฟังก์ชั่นที่มีชื่อ แต่มันถูกคัดค้านว่าทุกอย่างใน CoffeeScript เป็นฟังก์ชั่นที่ไม่ระบุชื่อและไม่มีฟังก์ชั่นที่มีชื่อ นี่เป็นความจริงแน่นอน CoffeeScript มีเพียงนิพจน์ฟังก์ชันที่สามารถเก็บไว้ในตัวแปรได้ แต่ฉันไม่คิดว่านั่นหมายความว่าการเรียกชื่อฟังก์ชันนี้ผิด

อย่างที่ฉันเห็นมันเป็นฟังก์ชั่นที่มีชื่อเพราะฟังก์ชั่นที่ได้รับการตั้งชื่อ จริงมันไม่ใช่ฟังก์ชั่นที่ตั้งชื่อในลักษณะเดียวกับภาษาอื่น ๆ ที่มีชื่อฟังก์ชั่น แต่ฉันคิดว่ามันใกล้พอที่จะเรียกมันว่าฟังก์ชั่นที่มีชื่อไม่เหมาะสม เพื่อยืนยันเป็นอย่างอื่นก็ดูเหมือนว่าจะเป็น nitpicking

ฉันออกไปทานข้าวกลางวันด้วยความคิดว่าการยืนยันว่านี่ไม่ใช่ฟังก์ชั่นที่ตั้งชื่อหรือไม่


3
นี่เป็นคำถามทั้งหมดใช่มั้ย :-)
Mat

@ Mat, ใช่ดูเหมือนว่าฉันไม่สามารถหลีกเลี่ยง nitpicking เกี่ยวกับ nitpicking
Winston Ewert

สำหรับกลุ่มเล็ก ๆ ของโปรแกรมเมอร์ที่ฉันคุยด้วย (นอก programmers.SE นั่นคือ) พวกเขาส่วนใหญ่พูดว่าใช้ชื่อฟังก์ชั่นที่มีชื่อของ JavaScript เพื่อใช้เป็น "คลาส" (ตัวสร้าง) ในขณะที่ฟังก์ชั่นที่ไม่ระบุชื่อ
Sal

1
"เพียงแค่ nitpicking" หมายถึงคำตอบไม่สำคัญและการเข้าใจความละเอียดอ่อนของภาษานั้นไม่ได้เป็นเป้าหมายที่คู่ควร
user229044

ฉันสามารถดูมันแบบอะนาล็อกกับ CoffeeScript: foo = ->เป็นเพียงฟังก์ชั่นเก่าแบบธรรมดาในขณะที่class Fooเป็นตัวสร้าง ฉันไม่เห็นเหตุผลว่าทำไมfoo = ->ควรเรียกชื่อแบบไม่ระบุชื่อ
Sal

คำตอบ:


20

CoffeeScript เชื่อมโยงกับ JavaScript อย่างไม่สิ้นสุดและ JavaScript แตกต่างระหว่างนิพจน์ต่อไปนี้:

function foo() { ... }
var foo = function () { ... }

ในความเป็นจริงคุณยังสามารถเขียน:

var foo = function bar () { ... }

เนื่องจากความแตกต่างนี้สำคัญใน JavaScript จึงเหมาะสมที่จะใช้คำเดียวกันเมื่อพูดถึง CoffeeScript อย่างไรก็ตาม CoffeeScript ไม่สนับสนุนสิ่งใด ๆ เช่นfunction foo ()ไวยากรณ์ดังนั้นเราจึงสามารถพูดได้ว่ามันไม่มีฟังก์ชั่น "ชื่อ"

เรียกอีกอย่างว่าชื่อเป็นส่วนหนึ่งของคำจำกัดความของฟังก์ชั่นในfunction foo() { ... }ซึ่งในกรณีอื่นคุณเพียงแค่สร้างฟังก์ชั่นและกำหนดให้กับตัวแปร นี่คือภาพสะท้อนตัวอย่างเช่นใน (มาตรฐาน) nameทรัพย์สินของฟังก์ชั่น: ในกรณีแรกที่foo.nameจะทำให้คุณและในครั้งที่สองมันจะทำให้คุณ"foo"""

นอกจากนี้ใน JavaScript สิ่งเหล่านี้แตกต่างกันในแง่ของวิธีการที่จะนำไปใช้กับขอบเขต: เวอร์ชันแรกคือ "hoisted" และพร้อมใช้งานตลอดขอบเขตที่คำจำกัดความที่สองพร้อมใช้งานหลังจากที่ได้รับมอบหมายแล้วเท่านั้น

โดยทั่วไปให้คิดว่ามันเป็นศัพท์แสงเฉพาะ JavaScript ซึ่งถูกโอนไปยัง CoffeeScript เพราะ CoffeeScript เกี่ยวข้องอย่างใกล้ชิดกับ JS


1
function foo () {}มันเป็นความจริงว่าไม่มีสิ่งดังกล่าวเป็น อย่างไรก็ตามคุณยังสามารถเริ่มต้นฟังก์ชั่นที่มีชื่อผ่านclassโครงสร้าง เพียงแค่ว่า CoffeeScript ที่คอมไพล์แล้ว (JavaScript ที่ได้) นั้นมีความละเอียดมากกว่าวิธีเขียนฟังก์ชันที่มีชื่อมากที่สุด
Sal

1
และยังมีข้อแม้ทางเทคนิค: fooร่างกายของฟังก์ชั่นของคุณจะไม่ถูกยก
Sal

1
jelivs: ไม่มีปัญหา หนึ่งการแก้ไขจากความคิดเห็นล่าสุดที่ฉันเขียนไว้ในคำตอบของคุณ: class fooร่างกายของฟังก์ชั่นของคุณจะไม่ถูกยกขึ้นไปด้านบนของไฟล์
Sal

เนื่องจาก CoffeeScript ไม่ได้สร้างความแตกต่างระหว่างฟังก์ชั่นที่มีชื่อและไม่ระบุชื่อเราสามารถพูดได้ว่าคำศัพท์นั้นถูกถ่ายโอนไปยัง CoffeeScript หรือไม่? ความแตกต่างของ Javascript นั้นไม่ได้มีความหมายอะไรในภาษานั้น
Winston Ewert

@WinstonEwert: มันสำคัญเพราะ CoffeeScript ใกล้กับ JavaScript มาก หลังจากที่ทุกคน "กฎทอง" คือ"มันก็แค่ JavaScript"
Tikhon Jelvis

5

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

CoffeeScript อยู่ห่างจาก JavaScript ไม่มากนักซึ่งคุณควรนิยามคำศัพท์ใหม่ที่ทั้งคู่แบ่งปันเพื่อหมายถึงสิ่งอื่นในภาษาเดียว CoffeeScript ไม่มีอยู่ในฟองสบู่บางส่วนลบออกจากการใช้งาน JavaScript ในแบบที่คุณอาจโต้แย้งว่า C ++ ถูกแยกออกจากแอสเซมบลี การทราบถึงความแตกต่างระหว่างฟังก์ชั่นที่ไม่ระบุชื่อกับฟังก์ชั่นที่มีชื่อนั้นสำคัญเพราะถ้าคุณคาดหวังว่าฟังก์ชั่น "ชื่อ" CoffeeScript ของคุณจะทำงานเหมือนฟังก์ชั่นที่มีชื่อจริง

doStuff() # I cause an error

# ... later

doStuff = (x,y) ->
  alert("Were I actually a named function, this would work!")

JavaScript ที่เทียบเท่าจะทำงานได้ดีโดยมีฟังก์ชันชื่อจริง :

doStuff(); // I work just fine!

// later....

function doStuff() {
  alert("I'm a real named function!")
}

คุณอาจพูดถูกว่าฉันแค่ "nitpicking" แต่อะไรนะ? ประเด็นที่ละเอียดอ่อนในเรื่องการเขียนโปรแกรมคอมพิวเตอร์และความถูกต้องของ "เทคนิค" เป็นสิ่งสำคัญ มันเป็นความแตกต่างระหว่างการเขียนโค้ดที่เกิดขึ้นกับการทำงานจริงและทำความเข้าใจว่าทำไมรหัสของคุณถูกต้อง


1
ถ้าฉันลองตัวอย่างของคุณใน Python มันก็ยังไม่ทำงาน ดังนั้นฉันไม่แน่ใจว่ามีส่วนเกี่ยวข้องกับฟังก์ชั่นที่มีชื่อเทียบกับไม่ระบุชื่อ
Winston Ewert

1
@WinstonEwert ดูการอัปเดตของฉัน Python ไม่มีส่วนเกี่ยวข้องใด ๆ กับมันจริงๆ ...
user229044

@meager จุดของฉันคือฟังก์ชั่นที่มีชื่อไม่จำเป็นต้องทำอย่างนั้นแม้ว่าพวกเขาจะทำใน Javascript ดังนั้นการยกตัวเองจะไม่ตัดสิทธิ์การใช้งานฟังก์ชั่นของ CoffeeScript
Winston Ewert

ใช่คุณต้องเข้าใจว่าฟังก์ชั่นทั้งหมดใน CoffeeScript นั้นไม่ระบุชื่อ แต่นั่นไม่ได้หมายความว่าบางครั้งเราไม่สามารถหลวมคำศัพท์ได้ นั่นเป็นเหตุผลที่ฉันคิดว่า nitpicking ที่จะยืนยันว่าคุณไม่สามารถเรียกพวกเขาว่าชื่อฟังก์ชั่น
Winston Ewert

3

ฉันออกไปทานข้าวกลางวันด้วยความคิดว่าการยืนยันว่านี่ไม่ใช่ฟังก์ชั่นที่ตั้งชื่อหรือไม่

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


3

แน่นอนว่าไม่ใช่ nitpick, imo ฉันใช้มันอย่างกว้างขวางเพื่อความสะดวกในการอ่าน:

readfile()
dothis()
dothat()
thistoo()
writefile()

function readfile() {
    ...
}
...

ดังนั้น:

ฟังก์ชั่นชื่อจริงใน "coffeescript"

hello()

`function hello() {`
console.log 'hello'
dothings()
`}`

คุณหลบหนี JS บริสุทธิ์โดยใช้ backtick `

โปรดทราบว่าคุณไม่สามารถเยื้องในฟังก์ชั่นร่างกายของคุณ

ไชโย


1

อย่าเสียเวลาเถียงกับคนเดินเท้า มันไม่เคยเกิดผล ใช่ทุกคนรู้ว่าคุณหมายถึงอะไรโดย "ฟังก์ชั่นที่มีชื่อ" ใน CoffeeScript แม้ว่ามันจะไม่ถูกต้องทางเทคนิค ไม่การใช้คำศัพท์ทางเทคนิคที่ไม่ถูกต้อง แต่คำศัพท์ที่เข้าใจอย่างกว้างขวางนั้นไม่มีผลต่อความถูกต้องหรือความไม่ถูกต้องของวิธีแก้ปัญหาที่เสนอ เป็นไปได้ไหมที่จะมีความแม่นยำมากขึ้นโดยไม่ต้องใช้ถ้อยคำที่น่าอึดอัดใจ? อาจจะไม่. อย่างไรก็ตามนั่นไม่ได้หมายความว่าผู้คนจะปล่อยให้มันลื่น ลองนึกภาพผู้ชายคนนี้ในตอนท้ายของการสนทนา

เหตุผลที่ไม่ถูกต้องทางเทคนิคก็เพราะคุณยังไม่ได้ตั้งชื่อฟังก์ชั่นคุณได้ตั้งชื่อการอ้างอิงถึงฟังก์ชั่น พิจารณา:

foo = bar = ->
  console.log "What's my name?"

ชื่อฟังก์ชั่นคืออะไร? fooและbarทั้งคู่อ้างถึงฟังก์ชันเดียวกัน แต่มีชื่อแตกต่างกัน นอกจากนี้ยังสามารถกำหนดfooหรือbarกำหนดใหม่ได้ตลอดเวลาเพื่ออ้างอิงฟังก์ชันที่แตกต่างกันหรือแม้กระทั่งประเภทที่แตกต่างกันโดยสิ้นเชิงโดยไม่ต้องเปลี่ยนฟังก์ชั่นเอง


0

ดังนั้นวิธีที่ฉันอ่านนี้เป็นเช่นนี้:

เมื่อคุณประกาศฟังก์ชันในคอนโซล JavaScript ที่ใช้

var foo = function() { ... }

แล้วเรียกใช้fooโดยไม่ต้องวงเล็บจะส่งกลับ

function() { ... }

อย่างไรก็ตามหากคุณกำหนดโดยใช้

function foo() { ... }

จากนั้นเรียกใช้fooอีกครั้งโดยไม่มีวงเล็บ

function foo() { ... }

ในกรณีแรกฉันจะบอกว่าคุณกำลังประกาศตัวแปรชื่อ "foo" ที่จัดเก็บฟังก์ชันที่ไม่ระบุชื่อไว้ ในกรณีที่สองฉันจะบอกคุณว่าจริง ๆ แล้วประกาศฟังก์ชั่นที่ชื่อว่า "foo"

เนื่องจาก CoffeeScript ใช้รูปแบบแรกฉันยอมรับว่ามันถูกต้องทางเทคนิคว่าฟังก์ชันของ CoffeeScript เป็นฟังก์ชันที่ไม่ระบุชื่อทั้งหมดถูกเก็บไว้ในตัวแปรที่ตั้งชื่อ

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