K.Maebashi's BBS

ご自由に書き込んでください。雑談も可。
テスト書き込みの類はテスト用掲示板にどうぞ

[日付順表示] [日付順インデックス] [スレッド順インデックス]

新規投稿 | 開設者ホームページへ戻る | ヘルプ

[2314] UFOを飛ばそうの部分についての質問
投稿者:rike1019
2022/09/25 20:01:07

リスト9: lesson04_5.html(UFOを動かすことに成功) の20行目で、mainLoop();を呼んでいますが、まだ関数を定義する前の行です。 なぜ、JavaScriptでこれはエラーにならないのでしょうか? 私は「完全」初心者ではないのですが、python3では、 mainloop() def mainloop(): print("Hello, world!") と書くと「NameError: name 'mainloop' is not defined」とエラーが出ます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2315] Re:UFOを飛ばそうの部分についての質問
投稿者:(ぱ)こと管理人
2022/09/25 23:15:45

>リスト9: lesson04_5.html(UFOを動かすことに成功) >の20行目で、mainLoop();を呼んでいますが、まだ関数を定義する前の行です。 >なぜ、JavaScriptでこれはエラーにならないのでしょうか? これは、JavaScriptの「巻き上げ」(hoisting)と呼ばれる機能のおかげです。 https://developer.mozilla.org/ja/docs/Glossary/Hoisting JavaScriptがなぜこうしたのかといえば、単純に「その方が便利だと思ったから」 なのだと思います。たとえばJavaではメソッドの宣言順は動作に影響せず、 宣言前のメソッドも呼び出せます。もっと古い言語であるCでは、巻数は事前に 定義されていなければ呼び出せず、関数funcAがfuncBを呼び出し、 funcBがfuncAを呼び出すような相互呼び出しをやりたいときには、どちらか片方を 事前に「プロトタイプ宣言」しておく必要がありました(不便です)。 Cで不便だと思われていて、Javaでは改善されたわけですから、Javaに似せた言語である JavaScriptでは、それはJavaに合わせるでしょう。 もっとも、さすがは変態言語というか、JavaScriptでは「巻き上げ」が 関数だけでなく変数に対しても、しかも関数内の変数に対しても適用されるので、 いろいろ混乱の元になっています。 https://analogic.jp/hoisting/ >私は「完全」初心者ではないのですが、python3では、 >mainloop() >def mainloop(): > print("Hello, world!") >と書くと「NameError: name 'mainloop' is not defined」とエラーが出ます。 pythonではなぜ関数を先に定義しておく必要があるかといえば、pythonでは 関数定義のdefは通常の実行文であり、それが実行されて初めて関数が定義されるからです (逆に言うと、JavaScriptやJavaやCでは、関数定義は実行文ではありません)。 pythonのdefは単なる文なので、たとえばif文の中でdefができます。 a = 10; if a == 10: def func(): print("hoge") else: def func(): print("piyo") func() このコードは、最初にaに代入する値によって、funcの定義が変わります。 CやJavaのような言語では、こういうことはできません。CやJavaでは、関数定義は、 コンパイルの時点で決まります。 JavaScriptはJavaに似せた言語なので、これを引き継いだのだと思います。 ではJavaScriptではif文の中にfunctionは書けないのか、といえば、これがどうも 書けるようで、でも「結果は実装によって一貫性がない」そうです。さすがは変態言語。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/function | 関数は条件付きで宣言できます。つまり、関数文を if 文の中に入れ子にすることができますが、 | 結果は実装によって一貫性がないので、このパターンを本番コードでは使用すべきではありません。 | 条件付きの関数の作成には、代わりに関数式を使用してください。 私自身、CやJavaのプログラマなので、自分で言語を作ったときには、 型なし言語のcrowbarも、静的型付け言語のDiksamも、関数定義を実行文にはしませんでした。 http://kmaebashi.com/programmer/devlang/index.html なので、JavaScriptの関数定義については、このようにした気持ちはわかります。 変数定義まで(それもローカル変数まで)同じように巻き上げられるようにしたのは、 正直、理解不能ですが。
[この投稿を含むスレッドを表示] [この投稿を削除]