JavaScriptが変数をホイストするのはなぜですか?


94

JavaScriptが変数をホイストするのはなぜですか?

ホイストを実装することを決定したときの設計者の論理的根拠は何でしたか?これを行う他の人気のある言語はありますか?

ドキュメントや記録への関連リンクを提供してください。


7
私は疑うで、このことは歴史的だポイント、と私は真剣にそれはもともと「実装の容易さ」以外のものだった疑い。
デイブニュートン

4
正直なところ、ブレンダン・アイクに聞いてください、彼は非常に敏感なようです。
Felix Kling

22
この質問どのように建設的ではありませんか?
フランシスク

18
@FranciscはStackOverflowへようこそ。ここではdiv、jQueryでを移動するだけです
Xlaudius 2014年

20
これは本当に重要な質問です。許可されるべきだった。それは炎の餌ではありませんでした。巻き上げはJavaScriptがどのように機能するかを理解するためのコア要素の1つであり、「なぜ」はその言語のほとんどの教科書の扱いで扱われる正当な質問です。StackOverflowの人々がこのような人々の質問を絶えず踏みにじることはOKではありません。
ベアバリン2015

回答:


55

Stoyan Stefanovが「JavaScriptPatterns」の本で説明しているように、巻き上げはJavaScriptインタープリターの実装の結果です。

JSコードの解釈は2つのパスで実行されます。最初のパスで、インタープリターは変数と関数の宣言を処理します。

2番目のパスは、実際のコード実行ステップです。インタプリタは、関数式と宣言されていない変数を処理します。

したがって、「巻き上げ」の概念を使用して、このような動作を説明できます。


15
私は個人的に「巻き上げ」という言葉が本当に好きではありません。それはあなたが言及したように、現実には変数と関数の宣言は、魔法、現在のスコープの先頭に掲揚されているという誤った表現で、JSインタプリタを与えるバインディングのソースコードをスキャンし、その後、コードを実行します。
contactmatt 2013

JSが言語を最も誤解している理由がわかりました。これは、どのチュートリアルでも見られませんでした。そして、巻き上げ(およびインタープリターフロー)と混同されました。
Swapnil Patwa 2017

17
ええと、これは本当に理論的根拠を説明していません。シングルパスの通訳者(巻き上げには至らなかったでしょう)ははるかに簡単だったでしょう-それで、なぜデザイナーは2つのパスを選んだのですか?
ベルギ2018

1
これは、変数が特に持ち上げられる理由を説明していません。関数は意味がありますが、変数は意味がありません(ほとんどの場合)-バグだと思います。
ジョシュ・M.

Josh M.これは非常に広範囲に指定されているので、これは「バグ」ではないと思います...(ただし、この回答が実際には推論に答えないことに同意します)
JonasWilms19年

10

JSクリエーターのブレンダンアイクはかつて(ツイッターで)言った

「したがって、varホイストは、機能ホイストの意図しない結果であり、ブロックスコープはなく、1995年の急ぎの仕事としてのJSでした。」

彼はまた説明した…

「関数の巻き上げにより、トップダウンのプログラム分解が可能になります。「let rec」は無料で、宣言する前に呼び出します。varの巻き上げにはタグが付けられます。」

ブレンダン・アイク

これを行う他の人気のある言語はありますか?

同じ方法で変数を持ち上げる他の人気のある言語を私は知りません。私は、ActionScript(Flash開発で使用されるECMAScriptの別の実装)でさえ、巻き上げを実装していなかったと思います。これは、JavaScriptを学習している他の言語に精通している開発者にとって混乱とフラストレーションの原因となっています。

更新:コメントから、Pythonには同様の変数の巻き上げ動作があります。


2
これが質問に直接対処しようとする唯一の答えであるため、+ 1を与える。
デイモン

1
この答えをありがとう。@Damonに完全に同意します!
codingbryan

1
可変巻き上げがあるもう1つの人気のある言語はPythonです:stackoverflow.com/q/63337235/2326961
Maggyero

2

これは、javascriptインタープリターが2サイクルでコードを解釈するためです。

  1. コード補完/コンパイル:
  2. コードの実行:

第一サイクルでは、すべての変数と関数の宣言は、それが中で実行している関数のスコープの一番上に移動します。これは、作成するのに役立ちますvariableObjectsのためにexecution context実行前であっても関数の。

第2フェーズでは、値の割り当て、コードステートメント、および関数呼び出しが、期待どおりに1行ずつ実行されます。

ここでもう少し詳しく読んで ください。

それはあなたの行動を周りの周りに優れた画像を与えるだろうletconstclassも、それは変数や関数の間で、次の優先を宣言。


1
あなたはそれがデザインの選択の結果であることを暗示していますか?もしそうなら、あなたはあなたの答えにそれを明確に述べるべきです。しかし、ブレンダン・アイクの答えを読んで、それは望まれた機能だったかもしれません、それはあなたが最後の文をどのように解釈するかに依存します。ボトムラインは、私はまだ理由を確かに知っていない
Bombinosh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.