1. ホーム
  2. javascript

[解決済み] JavaScriptの関数の順番:なぜそれが重要なのか?

2022-05-16 07:47:43

質問

オリジナルの質問です。

JSHint は、私のJavaScriptが、その関数への呼び出しよりもさらにページの下で定義されている関数を呼び出したときに、文句を言います。しかし、私のページはゲーム用で、全体がダウンロードされるまではどの関数も呼び出されません。では、なぜ私のコードで関数が表示される順序が問題になるのでしょうか?

EDIT: 答えを見つけたかもしれません。

http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

私は心の中で唸っています。もう1日かけて、6,000行のコードを並び替えなければならないようです。javascriptの学習曲線は決して急ではありませんが、非常に長いです。

どのように解決するのですか?

tl;dr すべてがロードされるまで何も呼び出さないのであれば、問題ないでしょう。




編集: ES6宣言の一部もカバーする概要について ( let , const ): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet

この奇妙な動作は

  1. 関数をどのように定義し
  2. いつそれらを呼び出すか

以下に例を示します。

bar(); //This won't throw an error
function bar() {}

foo(); //This will throw an error
var foo = function() {}

bar();
function bar() {
    foo(); //This will throw an error
}
var foo = function() {}

bar();
function bar() {
    foo(); //This _won't_ throw an error
}
function foo() {}

function bar() {
    foo(); //no error
}
var foo = function() {}
bar();

というものがあるためです。 ホイスティング !

関数を定義する方法は2つあります。関数 宣言 と関数 . この違いは煩わしいし微々たるものなので、このちょっと間違ったことを言うと、もしあなたが以下のような書き方をしているなら、それは function name() {} のように書いているなら、それは 宣言 のような書き方をすると var name = function() {} (のように書くと(あるいはreturnに代入された無名関数、みたいな)、関数 .

まず、変数の扱いを見てみましょう。

var foo = 42;

//the interpreter turns it into this:
var foo;
foo = 42;

さて、どのように機能 の宣言は はどのように処理されるのでしょうか。

var foo = 42;
function bar() {}

//turns into
var foo; //Insanity! It's now at the top
function bar() {}
foo = 42;

var ステートメントを投げます。 作成 foo を一番上に持ってきていますが、まだ値を代入していません。次に関数宣言が来て、最後に値が foo .

そして、これはどうでしょうか?

bar();
var foo = 42;
function bar() {}
//=>
var foo;
function bar() {}
bar();
foo = 42;

のみが 宣言 foo は先頭に移動します。の呼び出しの後にのみ代入されます。 bar の呼び出しが行われた後、すべてのホイストが行われる前にあった場所になります。

そして最後に、簡潔さのために

bar();
function bar() {}
//turns to
function bar() {}
bar();

さて、機能的にはどうでしょうか。 ?

var foo = function() {}
foo();
//=>
var foo;
foo = function() {}
foo();

通常の変数と同じように、最初に foo を宣言します。 がスコープの最上位で宣言されると、値が割り当てられます。

2番目の例がなぜエラーを投げるのかを見てみましょう。

bar();
function bar() {
    foo();
}
var foo = function() {}
//=>
var foo;
function bar() {
    foo();
}
bar();
foo = function() {}

前にも見たように、作成するのは foo の作成だけがホイストされ、代入は元の (ホイストされていない) コードに現れている場所に行われます。 このとき bar が呼ばれると、それは foo が値を割り当てる前なので foo === undefined . さて、関数本体である bar を実行しているようなものです。 undefined() というように、エラーを投げます。