CoffeeScript và các hàm được đặt tên


10

Ở những nơi khác , một cuộc tranh luận đã nảy sinh về thuật ngữ của một hàm được đặt tên trong CoffeeScript. Cụ thể là ai đó đã đề cập đến một cái gì đó như thế này:

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

như một chức năng được đặt tên. Nhưng nó đã bị phản đối rằng mọi thứ trong CoffeeScript đều là các hàm ẩn danh và không có các hàm được đặt tên. Điều này chắc chắn là đúng, CoffeeScript chỉ có các biểu thức hàm mà sau đó có thể được lưu trữ trong một biến. Nhưng tôi không nghĩ điều đó có nghĩa là sai khi gọi đây là một chức năng được đặt tên.

Như tôi thấy, nó là một hàm được đặt tên bởi vì nó là một hàm đã được đặt tên. Đúng, nó không phải là một chức năng được đặt tên theo cùng một cách mà một số ngôn ngữ khác đã đặt tên cho các chức năng, nhưng tôi nghĩ rằng nó đủ gần để không gọi nó là một chức năng được đặt tên. Để nhấn mạnh khác chỉ có vẻ là nitpicking.

Tôi có ra ngoài ăn trưa với suy nghĩ rằng khăng khăng rằng đây không phải là một chức năng được đặt tên chỉ là nitpicking?


3
Đây không phải là toàn bộ câu hỏi, tốt, nitpicking? :-)
Mat

@Mat, vâng, có vẻ như tôi không thể tránh được việc nitpicking về nitpicking
Winston Ewert

Đối với nhóm lập trình viên nhỏ mà tôi nói chuyện (bên ngoài lập trình viên. Đó là), họ chủ yếu nói sử dụng các hàm có tên JavaScript để sử dụng làm "lớp" (hàm tạo), trong khi các hàm ẩn danh được lưu trữ trong các biến cho các hàm cũ đơn giản.
Sal

1
"Chỉ cần nitpicking" ngụ ý câu trả lời không thành vấn đề, và hiểu rằng sự tinh tế của ngôn ngữ không phải là một mục tiêu xứng đáng.
dùng229044

Tôi có thể xem nó tương tự như CoffeeScript: foo = ->chỉ là một hàm cũ đơn giản, trong khi class Foolà một hàm tạo. Tôi thấy không có lý do tại sao foo = ->nên được gọi là ẩn danh.
Sal

Câu trả lời:


20

CoffeeScript gắn chặt với JavaScript và JavaScript phân biệt giữa các biểu thức sau:

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

Trong thực tế, bạn thậm chí có thể viết:

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

Vì sự khác biệt này quan trọng trong JavaScript, nên sử dụng các thuật ngữ tương tự khi nói về CoffeeScript là điều hợp lý. Tuy nhiên, CoffeeScript không hỗ trợ bất cứ điều gì như function foo ()cú pháp, vì vậy chúng tôi có thể nói nó không có chức năng "được đặt tên".

Theo một nghĩa nào đó, tên là một phần của định nghĩa hàm trong function foo() { ... }, trong trường hợp khác bạn chỉ cần tạo một hàm và gán nó cho một biến. Điều này được phản ánh, ví dụ, trong thuộc tính (không chuẩn) namecủa các hàm: trong trường hợp đầu tiên, foo.namesẽ cung cấp cho bạn "foo"và trong lần thứ hai, nó sẽ cung cấp cho bạn "".

Ngoài ra, trong JavaScript, chúng cũng khác nhau về cách chúng được giới thiệu về phạm vi: phiên bản đầu tiên được "nâng lên" và có sẵn trong phạm vi của nó, nơi định nghĩa thứ hai chỉ khả dụng sau khi được gán.

Về cơ bản, chỉ cần nghĩ về nó như biệt ngữ dành riêng cho JavaScript, được chuyển sang CoffeeScript vì CoffeeScript có liên quan mật thiết đến JS.


1
Đúng là không có một thứ như a function foo () {}. Tuy nhiên, bạn vẫn có thể khởi tạo một hàm được đặt tên thông qua classcấu trúc. Chỉ là CoffeeScript được biên dịch (JavaScript kết quả) dài dòng hơn nhiều so với cách hầu hết sẽ viết một hàm được đặt tên.
Sal

1
Ngoài ra, có một cảnh báo kỹ thuật: foocơ thể của bạn sẽ không được nâng lên.
Sal

1
jelivs: không vấn đề gì Một điều chỉnh từ nhận xét cuối cùng tôi đã viết trên câu trả lời của bạn: class foocơ thể chức năng của bạn sẽ không được đưa lên đầu tệp.
Sal

Vì CoffeeScript không tạo ra sự khác biệt giữa các hàm được đặt tên và ẩn danh, chúng ta có thể thực sự nói rằng thuật ngữ này được chuyển sang CoffeeScript không? Sự khác biệt của Javascript đơn giản là không có nghĩa gì trong ngôn ngữ đó.
Winston Ewert

@WinstonEwert: Nó quan trọng vì CoffeeScript rất gần với JavaScript. Rốt cuộc, "nguyên tắc vàng" là: "Đó chỉ là JavaScript" .
Tikhon Jelvis

5

Điều đáng chú ý là người dùng tuyên bố rõ ràng rằng họ đang biến một "hàm ẩn danh thành một hàm được đặt tên", cả hai thuật ngữ này đều có ý nghĩa mạnh mẽ, hiện có và các chức năng khác nhau đáng chú ý trong thế giới JavaScript. Với ý nghĩa hiện có, họ đã không làm điều đó, và tôi đã chỉ ra điều này.

CoffeeScript không bị xóa khỏi JavaScript mà bạn nên định nghĩa lại các thuật ngữ mà cả hai cùng chia sẻ để có nghĩa là một thứ khác trong một ngôn ngữ. CoffeeScript không tồn tại trong một số bong bóng, được xóa khỏi triển khai JavaScript theo cách bạn có thể lập luận rằng C ++ được tách ra khỏi hội. Biết được sự khác biệt giữa hàm ẩn danh và hàm có tên là vấn đề , bởi vì nếu bạn mong đợi hàm CoffeeScript "có tên" của mình hoạt động giống như một hàm có tên thực tế , bạn sẽ thất vọng:

doStuff() # I cause an error

# ... later

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

JavaScript tương đương sẽ hoạt động tốt, với chức năng có tên thật :

doStuff(); // I work just fine!

// later....

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

Bạn có thể đúng rằng tôi chỉ "nitpicking", nhưng vậy thì sao? Những điểm tinh tế trong vấn đề lập trình máy tính , và "đúng" về mặt kỹ thuật là rất quan trọng. Đó là sự khác biệt giữa viết mã xảy ra để làm việc và thực sự hiểu lý do tại sao mã của bạn là chính xác .


1
Nếu tôi đã thử ví dụ của bạn trong Python chẳng hạn, nó vẫn không hoạt động. Vì vậy, tôi không chắc có liên quan gì đến các chức năng được đặt tên và ẩn danh.
Winston Ewert

1
@WinstonEwert Xem cập nhật của tôi. Python thực sự không có gì để làm với nó ...
user229044

@meager, quan điểm của tôi là các hàm được đặt tên không nhất thiết phải hoạt động theo cách đó, mặc dù chúng hoạt động trong Javascript. Do đó, bản thân việc nâng hàng không đủ tiêu chuẩn cho các chức năng của CoffeeScript khỏi bị coi là có tên.
Winston Ewert

Có, bạn phải hiểu rằng tất cả các hàm trong CoffeeScript đều ẩn danh (thực ra, tôi muốn nói rằng chúng đều là các biểu thức hàm). Nhưng điều đó không có nghĩa là đôi khi chúng ta không thể lỏng lẻo với thuật ngữ. Đó là lý do tại sao tôi nghĩ rằng nitpicking của nó để khẳng định rằng bạn không bao giờ có thể gọi chúng là các chức năng được đặt tên.
Winston Ewert

3

Tôi có ra ngoài ăn trưa với suy nghĩ rằng khăng khăng rằng đây không phải là một chức năng được đặt tên chỉ là nitpicking?

Không. Xét cho cùng, về mặt ngữ nghĩa, tham chiếu hàm của bạn được lưu trữ trong một biến, mà bạn có thể tham chiếu qua một tên biến .


3

Chắc chắn không phải là một nitpick, imo. Tôi sử dụng nó rộng rãi để dễ đọc:

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

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

Như vậy:

Hàm có tên thật trong "coffeescript"

hello()

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

Bạn thoát khỏi JS thuần túy thông qua backtick `

Lưu ý rằng bạn không thể thụt vào cơ thể chức năng của bạn.

Chúc mừng


1

Đừng lãng phí thời gian để tranh cãi với giáo viên. Nó không bao giờ có kết quả. Vâng, mọi người đều biết ý của bạn về "hàm được đặt tên" trong CoffeeScript, ngay cả khi về mặt kỹ thuật không chính xác. Không, sử dụng thuật ngữ không chính xác nhưng được hiểu rộng rãi không ảnh hưởng đến tính đúng đắn hoặc không chính xác của giải pháp được đề xuất. Có thể chính xác hơn mà không đạt được một chút lúng túng của cụm từ? Chắc là không. Tuy nhiên, điều đó không có nghĩa là mọi người sẽ để nó trượt. Chỉ cần tưởng tượng anh chàng này ở đầu kia của cuộc trò chuyện.

Lý do nó không chính xác về mặt kỹ thuật là vì bạn chưa đặt tên hàm, bạn đã đặt tên tham chiếu cho hàm. Xem xét:

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

Tên của chức năng là gì? foobarcả hai đều tham chiếu cùng một chức năng, nhưng có tên khác nhau. Ngoài ra, foohoặc barcó thể được chỉ định lại bất cứ lúc nào để tham chiếu một chức năng khác, hoặc thậm chí là một loại khác hoàn toàn, mà không thay đổi chính chức năng đó.


0

Vì vậy, cách tôi đọc nó là như thế này:

Khi bạn khai báo một hàm trong bảng điều khiển JavaScript bằng cách sử dụng

var foo = function() { ... }

và sau đó gọi foomà không có dấu ngoặc đơn, nó trả về

function() { ... }

Tuy nhiên, nếu bạn xác định nó bằng cách sử dụng

function foo() { ... }

và sau đó gọi foolại mà không có dấu ngoặc đơn, nó trả về

function foo() { ... }

Trong trường hợp đầu tiên, tôi muốn nói rằng bạn đang khai báo một biến có tên "foo" lưu trữ một hàm ẩn danh trong đó. Trong trường hợp thứ hai, tôi muốn nói rằng bạn thực sự đang khai báo một hàm có tên là "foo".

Vì CoffeeScript sử dụng mẫu đầu tiên, tôi đồng ý rằng về mặt kỹ thuật, các hàm của CoffeeScript là tất cả các hàm ẩn danh được lưu trữ trong các biến được đặt tên.

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.