目次
2. ブロックレベルのスコープがない" >2. ブロックレベルのスコープがない

3. 変数のホイスティング(ホスティング)" >
3. 変数のホイスティング(ホスティング)
ホームページ ウェブフロントエンド jsチュートリアル JavaScript のスコープと変数を詳しく見る

JavaScript のスコープと変数を詳しく見る

Mar 14, 2018 pm 03:57 PM
javascript js 範囲

この記事では JavaScript のスコープと変数について説明します。JavaScript のスコープと変数について知らない場合、または JavaScript のスコープと変数に興味がある場合は、この記事を見てみましょう。ナンセンスはカットして本題に進みましょう

変数スコープ


スコープ: 変数が宣言される領域であり、変数や関数のアクセス可能なスコープでもあります。グローバルに宣言された変数はグローバルに参照可能であり、関数内で宣言された変数が関数内でのみアクセス可能である場合、それらはローカル変数と呼ばれます。

注意すべき点がいくつかあります:

1.JavaScript (ES5 および ES6 以前) にはブロックレベルのスコープはなく、関数スコープとグローバル スコープのみです。 for ループ内で定義された変数には関数レベルのスコープがあります。

2. 変数が関数内で宣言されていないか、var なしで宣言されている場合、それはグローバル変数であり、グローバル スコープを持ちます。 特別: var a = b = c = 0; b と c はグローバル変数です

3.変数のスコープは、変数のスコープがjsコードの解析段階ですでにルールを完了しているため、変数のスコープは宣言された時点に基づきます。

単純なケース:

	//变量的作用域
	var t = 90;  //全局作用域,在js代码中任何一个地方都可以访问

	function f1(){  //f1函数 在全局作用域中

		var t2 = 10;  //t2是f1函数内部变量,只有在f1内可访问
		console.log(t2);

		function f2(){ //f2函数  在f1函数的作用域中
			var t3 = 20;//只能在f2函数内部才能访问
			console.log(t3);
			return t2*t3;  // 访问了父级作用域中的t3
		}
		return f2();

	}
	var m = f1();

	console.log(m);
ログイン後にコピー

2. ブロックレベルのスコープがない

JavaScriptにはブロックレベルのスコープがないことを前述しましたが、これは以前のes5とes6用です。 9 (let const など)。 for ループと while ループ で定義された変数のスコープは、関数レベルのスコープです。

例:

	//没有块级作用域
	function f1(){
		for(var i=0;i<10;i++){//i变量是在for中定义的
			console.log(i);//打印1-9
		}
		console.log(i);//可以访问到i变量  打印10   而在c++ Java等语言中是不行的
	}

	f1();
ログイン後にコピー


3. 変数のホイスティング(ホスティング)


jsエンジンがjsを実行するときコードを入力すると、最初にグローバル EC が作成されます(コンテキスト) と関数の EC (関数がある場合)、EC を作成するときに、現在のユーザー ドメインで宣言された変数が未定義に初期化されています。これを初期化するにはどうすればよいですか? JS エンジンはまず現在のスコープで変数定義 var を探します。この定義が見つかった場合は、その定義がスコープの先頭に昇格され、メモリ (つまり EC の変数オブジェクト VO) に保存されます。未定義にします。

ケース:

	var a = 10;

	function f1(){
		//在这里首先会创建f1的执行上下文  并把里面的变量初始化为undefined
		console.log(a);  //代码执行到这里的时候, js引擎会去当前作用域内存中问有没有这个变量的声明,发现有,那么就给他初始的undefined

		//假如说下面没有var变量进行定义a,那么js就会向父级作用域中去找这个变量,直到找到为止

		var a = 19;  //在这里给a赋值了19

		console.log(a); // 打印了19
	}

	f1();

	console.log(a);  //这里无疑是10 没什么问题
ログイン後にコピー

したがって、JS エンジンはコンテキストを作成するときに、必要な変数をプロモートします。これは、ES6 のセキュリティ保護メカニズムであると言えます。について詳しく議論されています。

注: 変数宣言と関数宣言が同じ名前の場合、関数の方が優先されます。


	console.log(b); //打印b(){}

	var b = 9;

	function b(){

	}

	console.log(b); //打印9
ログイン後にコピー

関数が前に昇格しているので、最初に出力されるのは間違いなく b(){} です。js は動的言語なので、b は 9 に再割り当てされ、前の関数が上書きされます。

ケース 1:

	if ("a" in window) {
		var a = 1;
	}
	console.log(a);
ログイン後にコピー

まずコードを見ました。答えは何ですか?それは

Uncaught ReferenceError: a が定義されていません ではないでしょうか?

教えてください、 答えは 1 です


まず第一に、var a = 1 は実際にはグローバル変数 ( window オブジェクトの属性は

の下にあります)。これは、if がブロック スコープではないため、es5 より前の JavaScript にはブロック スコープが存在しませんでした。したがって、この

条件付き判断が成立します。

もう一度見てください:

	if (!("a" in window)) {
		var a = 1;
	}
	console.log(a);
ログイン後にコピー

それで、これはどうあるべきですか?条件が確立されておらず、 a への代入が成功していないため、答えは未定義です。デフォルトは

未定義

です。

案例二:

	fun();

	console.log(a);
	console.log(b);
	console.log(c);

	function fun(){
		var a = b = c = 10;
		console.log("fun中的a="+a);
		console.log("fun中的b="+b);
		console.log("fun中的c="+c);
	}
ログイン後にコピー


你得答案是什么?

答案是:

由于a没有定义,所以直接报错,下面的两行代码被阻止执行了,假如把外面的console.log(a)注释掉呢?

	fun();

	//console.log(a);
	console.log(b);
	console.log(c);

	function fun(){
		var a = b = c = 10;
		console.log("fun中的a="+a);
		console.log("fun中的b="+b);
		console.log("fun中的c="+c);
	}
ログイン後にコピー

输出的是:


为什么外面b c都会是10呢? 原因就是var a = b = c = 10 ;其中b c就是全局变量,如果你想定义三个内部变量,那么应该这样定义:

var a = 10 ,b = 10, c = 10;

弄懂了以上这些区别,基本上变量提升就没什么大问题了。以上就是本篇文章的所有内容,大家要是还不太了解的话,可以自己多实现两边就很容易掌握了哦!

相关推荐:

JS关于作用域的一个问题

js函数和变量的提升及闭包讲解

以上がJavaScript のスコープと変数を詳しく見るの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

C言語でのtypedef構造体の使い方 C言語でのtypedef構造体の使い方 May 09, 2024 am 10:15 AM

typedef struct は、構造体の使用を簡素化するために構造体型のエイリアスを作成するために C 言語で使用されます。構造体の別名を指定することで、新しいデータ型を既存の構造体に別名付けします。利点としては、可読性の向上、コードの再利用、型チェックなどが挙げられます。注: エイリアスを使用する前に構造体を定義する必要があります。エイリアスはプログラム内で一意であり、宣言されているスコープ内でのみ有効である必要があります。

Javaで期待される変数を解決する方法 Javaで期待される変数を解決する方法 May 07, 2024 am 02:48 AM

Java における変数の期待値の例外は、変数の初期化、null 値の使用、およびローカル変数のスコープの認識によって解決できます。

JSのクロージャーの長所と短所 JSのクロージャーの長所と短所 May 10, 2024 am 04:39 AM

JavaScript クロージャーの利点には、変数スコープの維持、モジュール化コードの有効化、遅延実行、およびイベント処理が含まれますが、欠点としては、メモリ リーク、複雑さの増加、パフォーマンスのオーバーヘッド、およびスコープ チェーンの影響が挙げられます。

C++ で include は何を意味しますか C++ で include は何を意味しますか May 09, 2024 am 01:45 AM

C++ の #include プリプロセッサ ディレクティブは、外部ソース ファイルの内容を現在のソース ファイルに挿入し、その内容を現在のソース ファイル内の対応する場所にコピーします。主に、コード内で必要な宣言を含むヘッダー ファイルをインクルードするために使用されます。たとえば、標準入出力関数を組み込むための #include <iostream> などです。

C++ スマート ポインター: ライフサイクルの包括的な分析 C++ スマート ポインター: ライフサイクルの包括的な分析 May 09, 2024 am 11:06 AM

C++ スマート ポインターのライフ サイクル: 作成: スマート ポインターは、メモリが割り当てられるときに作成されます。所有権の譲渡: 移動操作を通じて所有権を譲渡します。リリース: スマート ポインターがスコープ外に出るか、明示的に解放されると、メモリが解放されます。オブジェクトの破壊: ポイントされたオブジェクトが破壊されると、スマート ポインターは無効なポインターになります。

C++ での関数の定義と呼び出しはネストできますか? C++ での関数の定義と呼び出しはネストできますか? May 06, 2024 pm 06:36 PM

できる。 C++ では、ネストされた関数の定義と呼び出しが可能です。外部関数は組み込み関数を定義でき、内部関数はスコープ内で直接呼び出すことができます。ネストされた関数により、カプセル化、再利用性、スコープ制御が強化されます。ただし、内部関数は外部関数のローカル変数に直接アクセスすることはできず、戻り値の型は外部関数の宣言と一致している必要があります。内部関数は自己再帰的ではありません。

Vueのletとvarの違い Vueのletとvarの違い May 08, 2024 pm 04:21 PM

Vue では、let と var の間で変数を宣言するときのスコープに違いがあります。 スコープ: var にはグローバル スコープがあり、let にはブロック レベルのスコープがあります。ブロックレベルのスコープ: var はブロックレベルのスコープを作成しません。let はブロックレベルのスコープを作成します。再宣言: var は同じスコープ内の変数の再宣言を許可しますが、let は許可しません。

js の this が指す状況がいくつかあります。 js の this が指す状況がいくつかあります。 May 06, 2024 pm 02:03 PM

JavaScript では、this のポインティング タイプには、1. グローバル オブジェクト、2. 関数呼び出し、4. イベント ハンドラー、5. アロー関数 (this の外側の継承) が含まれます。さらに、bind()、call()、および apply() メソッドを使用して、これが何を指すかを明示的に設定できます。

See all articles