ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript が var の事前解析と副作用を調査する

JavaScript が var の事前解析と副作用を調査する

高洛峰
高洛峰オリジナル
2016-11-28 14:39:081077ブラウズ

var の副作用

暗黙的なグローバル変数と明示的に定義されたグローバル変数の間には小さな違いがあり、それは、delete 演算子を使用して変数を未定義のままにする機能です。

var を通じて作成されたグローバル変数 (関数の外のプログラムで作成されたもの) は削除できません。

var なしで作成された暗黙的なグローバル変数 (関数内で作成されたかどうかに関係なく) は削除できます。

これは、技術的には、暗黙的なグローバル変数は実際にはグローバル変数ではなく、グローバル オブジェクトのプロパティであることを示しています。プロパティは delete 演算子で削除できますが、変数は削除できません:

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

ES5 厳密モードでは、宣言されていない変数 (前のコード スニペットの 2 つの否定的な例など) を操作すると、エラーがスローされます。

単一の var 形式

関数の先頭で単一の var ステートメントを使用することは、より便利な形式です:

関数に必要なすべてのローカル変数を検索する単一の場所を提供します

変数が定義されるのを防ぎます。定義される前に使用されるロジック エラー

は、宣言されたグローバル変数を覚えておくのに役立ちます。そのため、グローバル変数が少なくなります //zxx: ここで少し混乱しています...

コードが少なくなります (型、値、単一行補完) )

単一の var 形式は次のようになります:

function func() {
   var a = 1,
       b = 2,
       sum = a + b,
       myobject = {},
       i,
       j;
   // function body...
}

1 つの var ステートメントを使用して、カンマで区切って複数の変数を宣言できます。このように変数と値を同時に初期化すると良いでしょう。これにより、論理エラー (初期化されていないが宣言されたすべての変数の初期値が未定義) が防止され、コードの可読性が向上します。コードを確認すると、初期化された値に基づいて、これらの変数の一般的な目的 (オブジェクトとして使用されるか整数として使用されるかなど) を知ることができます。

前のコードの sum = a + b など、宣言時に実際の作業を行うこともできます。もう 1 つの例は、DOM (Document Object Model) 参照を使用する場合、DOM と一緒にローカル変数を指定する単一の var を使用することができます。次のコードに示すように、参照を参照します。

function updateElement() {
   var el = document.getElementById("result"),
       style = el.style;
   // 使用el和style干点其他什么事...
}

vars 変数の準備

JavaScript では、関数内の任意の場所で複数の var ステートメントを宣言でき、それらは関数の先頭にあるかのように表示されます。宣言は同じように機能します。 、この動作はホイスティング (一時停止/上位解析/事前解析) と呼ばれます。変数を使用し、その後関数内でそれを再宣言すると、ロジック エラーが発生する可能性があります。 JavaScript の場合、変数が同じスコープ (同じ関数) 内にある限り、var 宣言の前に使用された場合でも、その変数は宣言されているとみなされます。次の例を見てください:

// 反例
myname = "global"; // 全局变量
function func() {
    alert(myname); // "undefined"
    var myname = "local";
    alert(myname); // "local"
}
func();

この例では、最初のアラートが「global」でポップアップし、2 番目のアラートが「loacl」でポップアップすると考えるかもしれません。最初のアラートの時点では myname が宣言されていなかったため、この期待は理解できます。この時点では、関数は当然グローバル変数 myname を参照する必要がありますが、これは実際の動作ではありません。最初のアラートは「未定義」としてポップアップ表示されます。これは、myname が (後で宣言されても) 関数のローカル変数として扱われ、すべての変数宣言が関数の先頭まで保留されるためです。したがって、この混乱を避けるには、使用するすべての変数を事前に宣言することが最善です。

上記のコード スニペットは次のように動作する可能性があります:

myname = "global"; // global variable
function func() {
   var myname; // 等同于 -> var myname = undefined;
   alert(myname); // "undefined"
   myname = "local";
   alert(myname); // "local"}
func();

完全を期すために、実行レベルでもう少し複雑なことについて触れてみましょう。コード処理は 2 つの段階に分かれています。最初の段階は、変数、関数の宣言、および通常の形式でのパラメーターの作成です。これは、コンテキストを解析して入力する段階です。 2 番目のフェーズはコードの実行で、関数式と非修飾識別子 (宣言された変数用) が作成されます。ただし、実際的な目的のために、ECMAScript 標準では定義されておらず、動作を記述するために一般に使用される「ホイスティング」の概念を採用します。

グローバル オブジェクトへのアクセス

ブラウザでは、コード内のどこからでも window 属性を介してグローバル オブジェクトにアクセスできます (window という名前のローカル変数を宣言するなど、とんでもないことをしない限り)。ただし、他のコンテキストでは、この便利なプロパティは別の名前で呼ばれる場合があります (またはプログラムで使用できない場合もあります)。ハードコーディングされたウィンドウ識別子を使用せずにグローバル オブジェクトにアクセスする必要がある場合は、任意のレベルの関数スコープで次の操作を行うことができます:

var global = (function () {
   return this;
}());

这种方法可以随时获得全局对象,因为其在函数中被当做函数调用了(不是通过new构造),this总是指向全局对象。实际上这个病不适用于ECMAScript 5严格模式,所以,在严格模式下时,你必须采取不同的形式。例如,你正在开发一个JavaScript库,你可以将你的代码包裹在一个即时函数中,然后从全局作用域中,传递一个引用指向this作为你即时函数的参数。


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