ホームページ > ウェブフロントエンド > jsチュートリアル > JavaScript のスコープと変数を詳しく見る

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

韦小宝
リリース: 2018-03-14 15:57:44
オリジナル
1467 人が閲覧しました

この記事では 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 サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート