Функції CoffeeScript та іменовані функції


10

В іншому випадку виник аргумент щодо термінології названої функції в CoffeeScript. Зокрема, хтось згадував щось подібне:

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

як названа функція. Але заперечували, що все в CoffeeScript - це анонімні функції, і немає іменованих функцій. Це, безумовно, так, у CoffeeScript є лише вирази функцій, які потім можуть зберігатися у змінній. Але я не думаю, що це означає, що невірно називати це іменованою функцією.

Як я бачу, це названа функція, оскільки її функція отримала ім'я. Правда, це не названа функція так само, як деякі інші мови назвали функції, але я вважаю її досить близькою, що називати її іменованою функцією недоцільно. Наполягати інакше просто здається, що зникає.

Я виходжу на обід, думаючи, що наполягати на тому, що це не названа функція, - це просто приниження?


3
Хіба це все питання не просто, ну анітрохи? :-)
Мат

@Mat, так, здається, я не можу уникнути дуріння з приводу азоту
Winston Ewert

Що стосується невеликого пулу програмістів, з яким я розмовляю (поза програмістами.SE, тобто), вони, як правило, говорять про використання названих функцій JavaScript для використання як "класи" (конструктори), а анонімні функції, що зберігаються у змінних, для звичайних старих функцій.
Сал

1
"Просто занурення" означає, що відповідь не має значення, і що розуміння тонкощів мови не є гідною метою.
користувач229044

Я міг би поглянути на це аналогічно CoffeeScript: foo = ->це лише звичайна стара функція, в той час class Fooяк конструктор. Я не бачу причин, чому foo = ->слід суворо називати анонімним.
Сал

Відповіді:


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 вони також відрізняються з точки зору того, як вони знайомляться з областю: перша версія є "піднятою" та доступною у всьому її масштабі, де друге визначення доступне лише після її призначення.

По суті, просто подумайте про це як на жаргоні, що відповідає JavaScript, який передається в CoffeeScript, оскільки CoffeeScript так тісно пов'язаний з JS.


1
Це правда, що не існує такого поняття, як function foo () {}. Однак ви можете все ще ініціалізувати названу функцію через classконструкцію. Тільки те, що компільований CoffeeScript (отриманий JavaScript) набагато більш багатослівний, ніж те, як більшість написала б названу функцію.
Сал

1
А також є технічний застереження: fooкорпус вашої функції не буде підніматися.
Сал

1
jelivs: немає проблем. Одне виправлення з останнього коментаря, який я написав на вашу відповідь: class fooорган вашого функціонування не буде підніматися до верхньої частини файлу.
Сал-

Оскільки CoffeeScript не робить різниці між названими та анонімними функціями, чи можемо ми реально сказати, що термінологія передається на CoffeeScript? Відмінність Javascript просто не означає нічого на цій мові.
Вінстон Еверт

@WinstonEwert: Це важливо, оскільки CoffeeScript так близько до JavaScript. Адже "золотим правилом" є: "Це просто JavaScript" .
Тихон Єлвіс

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!")
}

Можливо, ви маєте рацію, що я просто "забиваю", але що? Тонкі моменти в області комп'ютерного програмування справу , і бути «технічно» правильним є важливим. Це різниця між написанням коду, який трапляється в роботі, і власне розумінням того, чому ваш код правильний .


1
Якби я спробував твій приклад, наприклад, у Python, він все одно не вийшов би. Тож я не впевнений, що це має відношення до анонімних функцій vs.
Вінстон Еверт

1
@WinstonEwert Дивіться моє оновлення. Python насправді не має нічого спільного з цим ...
user229044

@meager, моя думка полягає в тому, що названі функції не обов'язково діють таким чином, хоча вони і в JavaScript. Таким чином, само піднімання не позбавляє функцій CoffeeScript від того, щоб вони вважалися названими.
Вінстон Еверт

Так, ви повинні розуміти, що всі функції в CoffeeScript є анонімними (насправді я б хотів сказати, що всі вони є виразами функцій). Але це не означає, що ми часом не можемо бути трохи розкутими з термінологією. Ось чому я вважаю, що його прищеплення наполягає на тому, що ви ніколи не можете назвати їх названими функціями.
Вінстон Еверт

3

Я виходжу на обід, думаючи, що наполягати на тому, що це не названа функція, - це просто приниження?

Ні. Зрештою, з точки зору семантики посилання на вашу функцію зберігається у змінній, на яку можна посилатися через ім'я змінної .


3

Однозначно, не нитка, 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 - це всі анонімні функції, що зберігаються в названих змінних.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.