ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptの変数宣言とグローバル変数のローカル変数置換の詳細説明

JavaScriptの変数宣言とグローバル変数のローカル変数置換の詳細説明

伊谢尔伦
伊谢尔伦オリジナル
2017-07-18 09:54:232333ブラウズ

関数本体の外で定義されたものはグローバル変数、関数本体の内部で定義されたものはローカル変数です。ここでの定義は、var による宣言を指します。

JavaScript には暗黙的なグローバルの概念があり、宣言されていない変数はグローバル オブジェクト プロパティになることを意味します。例:

function test(){
    myname = "huming";
    alert(myname);
}
test();  // "huming"
alert(myname);  //"huming"

2 つの結果は同じであり、myname がグローバル変数であることを示しています。

それでは、暗黙的なグローバル変数と明示的に定義されたグローバル変数の間に違いはあるのでしょうか? 。答えは間違いなく「はい」です。次の例を見てください:

// 定义三个全局变量
var global_test1 = 1;
global_test2 = 2; // 反面教材
(function () {
    global_test3 = 3; // 反面教材
}());
// 试图删除
delete global_test1; // false
delete global_test2; // true
delete global_test3; // true
// 测试该删除
alert(typeof global_test1); // "number"
alert(typeof global_test2); // "undefined"
alert(typeof global_test3); // "undefined"

上の例からわかるように、関数の外で var によって定義された global_test1 は削除できません。また、var によって定義されていない global_test2 と global_test3 は (関数の関数に関係なく) 削除されます。関数本体内で作成されるかどうか)。

要約すると、関数本体の外で var を通じて宣言されたグローバル変数は削除できませんが、暗黙的なグローバル変数は削除できます。

ここで注意すべき点: JavaScript には「ホイスティング」(一時停止/上位解析/事前解析) と呼ばれる動作があります。

例で説明しましょう:

var myname = "huming"; //声明全局变量
function test() {
    alert(myname);
    var myname = "local_huming";
    alert(myname);
}
test();

2 つのアラートの内容は一貫していると思いますか? ?明らかに一貫性がありませんが、一貫していることは言うまでもありません。 。実際の出力は、「unknown」、「local_huming」です。

上記の例は

var myname = "huming"; //声明全局变量
function test() {
  var myname;
  alert(maname);<br>  myname = "local_huming";
  alert(myname);    // "local"
}
test();

に相当します。alertが初めて出力するmynameはあなたが思っているようなグローバル変数ではなく、それと同じスコープ(関数本体)にあるローカル変数です。宣言はされていないものの、そのように扱われます。これを「吊り上げ」といいます。

これで明らかになるはずです。関数本体で変数を使用し、後でそれを再宣言すると、エラーが発生することがあります。

仕様の記述:

function test() {
   var a = 1,
       b = 2,
       c = a + b,
       d = {},
       e,
       f;
   // function body...
}

利点は次のとおりです:

1. すべてのローカル変数が関数の先頭で定義されるため、見つけやすくなります。

2. 変数が定義される前に使用される場合の論理エラーを防止します。

交換方法は?

JavaScript のパフォーマンスを向上させる方法に関して、最もよく聞かれるアドバイスは、グローバル変数の代わりにローカル変数を使用することです。このアドバイスは私の 9 年間の Web 開発の仕事の中で常に心に残り、一度も疑問に思ったことはありません。このアドバイスの根拠は、JavaScript のスコープと識別子解決 (識別子解決) メソッドの処理にあります。 , まず、JavaScript における関数の機能はオブジェクトを作成するプロセスであることを明確にする必要があります。各関数オブジェクトには [[Scope]] と呼ばれる内部プロパティがあり、関数の作成時のスコープ情報が含まれています。実際、[[Scope]] 属性はオブジェクトのリスト (変数オブジェクト) に対応しており、リスト内のオブジェクトには関数内からアクセスできます。たとえば、グローバル関数 A を作成した場合、A の [[Scope]] 内部プロパティには 1 つのグローバル オブジェクト (Global Object) のみが含まれます。また、A に新しい関数 B を作成した場合、B の [[Scope] ] 属性には次のものが含まれます。 2 つのオブジェクトがあり、関数 A の Activation Object オブジェクトが前にあり、グローバル オブジェクト (Global Object) が後ろにあります。

関数が実行されると、実行可能オブジェクト (実行オブジェクト) が自動的に作成され、スコープ チェーン (スコープ チェーン) にバインドされます。スコープ チェーンは、識別子解決のための次の 2 つの手順を通じて確立されます。

まず、関数オブジェクト[[Scope]]の内部プロパティ内のオブジェクトをスコープチェーンに順番にコピーします。

次に、関数が実行されると、このオブジェクトには this の定義、パラメーター (引数)、およびローカル変数 (名前付きパラメーターを含む) が含まれ、この Activation オブジェクト オブジェクトがアクションに配置されます。 . ドメインチェーンの先頭。

JavaScript コードの実行中に識別子が見つかると、識別子の名前に基づいて実行コンテキスト (実行コンテキスト) のスコープ チェーン内で識別子が検索されます。スコープ チェーン内の最初のオブジェクト (関数のアクティブ化オブジェクト) から開始して、見つからない場合はスコープ チェーン内の次のオブジェクトを検索し、識別子の定義が見つかるまで同様に検索します。スコープ内の最後のオブジェクト、つまりグローバル オブジェクトが見つからない場合は、エラーがスローされ、変数が未定義であることをユーザーに通知します。これは、ECMA-262 標準で説明されている関数実行モデルと識別子解決 (Identifier Resolution) プロセスであり、ほとんどの JavaScript エンジンが実際にこの方法で実装されていることがわかります。 ECMA-262 はこの構造体の使用を義務付けているわけではなく、関数のこの部分についてのみ説明していることに注意してください。

以上がJavaScriptの変数宣言とグローバル変数のローカル変数置換の詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。