CoffeeScriptと名前付き関数


10

他の場所では、CoffeeScriptの名前付き関数の用語について議論が生じています。特に誰かがこのようなものを参照しました:

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

名前付き関数として。しかし、CoffeeScriptのすべてが匿名関数であり、名前付き関数がないことに反対しました。これは確かに真実です。CoffeeScriptには、変数に格納できる関数式しかありません。しかし、これを名前付き関数と呼ぶのが間違っていることを意味しているとは思いません。

私が見ると、名前が付けられた関数なので、名前付き関数です。確かに、他のいくつかの言語が名前付き関数を持っているのと同じように名前付き関数ではありませんが、名前付き関数と呼ぶのは不適切ではないほど近いと思います。そうでないと主張することは、つまらないことのようです。

これは名前付きの関数ではないと主張することは単なるつまらないことだと思って、昼食に出かけますか?


3
この質問全体は、まあまあ、つまらないですよね?:-)
Mat

@マット、はい、私は手抜きについての手抜きを避けられないようです
Winston

私が話しているプログラマーの小さなプール(つまり、programmers.SEの外)では、JavaScriptの名前付き関数を「クラス」(コンストラクター)として使用する一方、匿名関数は単純な古い関数の変数に格納されます。
Sal

1
「ただつまらない」ということは、答えが問題ではないことを意味し、言語の微妙さを理解することは価値のある目標ではありません。
user229044 2013年

私はそれを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"れ、2番目のケースではが表示されます""

さらに、JavaScriptでは、スコープへの導入方法も異なります。最初のバージョンは「ホイスト」され、スコープ全体で使用できます。2番目の定義は、割り当てられた後にのみ使用できます。

基本的に、それをJavaScript固有の専門用語と考えてください。CoffeeScriptはJSと非常に密接に関連しているため、CoffeeScriptに転送されます。


1
のようなものがないのは事実ですfunction foo () {}。ただし、class構文を使用して名前付き関数を初期化することはできます。コンパイルされたCoffeeScript(結果のJavaScript)は、ほとんどが名前付き関数を作成する方法よりもはるかに詳細です。
Sal

1
また、技術的な警告があります。foo関数の本体は巻き上げられません。
Sal

1
jelivs:問題ありません。私があなたの回答に書いた最後のコメントからの1つの訂正:あなたclass fooのの関数本体はファイルの先頭に引き上げられません。
Sal

CoffeeScriptは名前付き関数と匿名関数を区別しないので、用語がCoffeeScriptに移行したと本当に言えるでしょうか。Javascriptの違いは、単にその言語では何も意味しない。
Winston

@WinstonEwert:CoffeeScriptがJavaScriptに非常に近いため、問題なります。結局のところ、「ゴールデンルール」は「それ単なるJavaScriptです」です。
Tikhon Jelvis 2013年

5

ユーザーが「匿名関数を名前付き関数に変換する」ことを明示したことは注目に値します。どちらの用語も、強力で既存の意味を持ち、特にJavaScriptの世界では機能が異なります。既存の意味を考えると、それらはそのようなことをしておらず、私はこれを指摘しました。

CoffeeScriptはJavaScriptからそれほど遠くないので、1つの言語で別のものを意味するように両方が共有する用語を再定義する必要があります。CoffeeScriptはいくつかのバブルには存在せず、C ++がアセンブリから分離されていると主張する方法でJavaScript実装から削除されました。無名関数と名前付き関数の違いを知ることは重要です。「名前付き」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で例を試した場合、それでも機能しません。だから私はそれが名前付き関数と無名関数と関係があるかどうかわかりません。
Winston Ewert 2013年

1
@WinstonEwert私のアップデートを参照してください。Pythonは本当にそれとは何の関係もありません...
user229044

@meager、私の要点は、名前付き関数はJavascriptで動作しますが、必ずしもそのように動作するわけではないということです。したがって、それ自体を巻き上げることは、CoffeeScriptの関数が名前付きと見なされることを失格にはしません。
Winston Ewert 2013年

はい、CoffeeScriptのすべての関数は匿名であることを理解する必要があります(実際、これらはすべて関数式であると言いたいです)。しかし、それは私たちが時々用語に少しゆったりすることができないことを意味しません。だからこそ、名前付きの関数を呼び出すことはできないと主張するのは簡単ではないと思います。
Winston Ewert 2013年

3

これは名前付きの関数ではないと主張することは単なるつまらないことだと思って、昼食に出かけますか?

いいえ、結局のところ、セマンティクスに関しては、関数参照は変数に格納され、変数を介して参照できます。


3

間違いなく、こつこつではありません、イモ。私は読みやすくするために広く使用しています。

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

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

したがって:

「coffeescript」の実際の名前付き関数

hello()

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

バックティックを介して純粋なJSをエスケープします `

関数本体ではインデントできないことに注意してください。

乾杯


1

ペダントと議論する時間を無駄にしないでください。それは決して実り多いことではありません。はい、技術的に正しくない場合でも、CoffeeScriptの "名前付き関数"の意味を誰もが知っています。いいえ、技術的に正しくないが広く理解されている用語を使用しても、提案されたソリューションの正確性や不正確さには影響しません。言い回しにぎこちなくすることなく、より正確にすることは可能ですか?おそらく違います。しかし、それは人々がそれを滑らせることを意味するわけではありません。会話の反対側にいるこの男を想像してみてください。

技術的に正しくない理由は、関数に名前を付けていないため、関数への参照に名前を付けているためです。検討してください:

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

関数の名前は何ですか? foobarはどちらも同じ関数を参照していますが、名前が異なります。また、fooまたはbarをいつでも再割り当てして、関数自体を変更せずに、別の関数を参照したり、別の型を参照したりすることもできます。


0

だから、私はこれを読む方法は次のようになります:

次を使用してJavaScriptコンソールで関数を宣言する場合

var foo = function() { ... }

fooかっこなしで起動すると、次を返します

function() { ... }

ただし、次のように定義した場合

function foo() { ... }

fooかっこなしでもう一度呼び出すと、戻ります

function foo() { ... }

最初のケースでは、匿名関数を格納する "foo"という名前の変数を宣言していると思います。2番目のケースでは、「foo」という名前の関数を実際に宣言していると思います。

CoffeeScriptは最初のパターンを使用するので、CoffeeScriptの関数はすべて名前付き変数に格納されている匿名関数であることが技術的に正しいことに同意します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.