首頁  >  文章  >  web前端  >  細說JavaScript中的作用域與變數

細說JavaScript中的作用域與變數

韦小宝
韦小宝原創
2018-03-14 15:57:441443瀏覽

本篇文章講述了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.變數提升( hositing)


js引擎在執行js程式碼的時候,首先會先建立全域的EC(上下文)和函數的EC(如果有函數),在創建EC的時候已經把當前作

用域裡面宣告的變數初始化為undefined,怎麼初始化呢? js引擎首先會在目前作用域去找var這個變數定義,發現有這個定義,那麼就

#把它提升到作用域的最前面,並且保存在記憶體中(即EC中的變數物件VO),設為undefined。

案例:

#
	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,覆寫之前的function。

案例一:

	if ("a" in window) {
		var a = 1;
	}
	console.log(a);


首先看到你段程式碼,你的答案是什麼?會不會是Uncaught ReferenceError: a is not defined?

告訴你,答案是1

首先,你要清楚var a = 1其實是定義了一個全域變數(屬於window物件下的屬性),因為if並不是區塊作用域,JavaScript中es5之前沒有區塊作用域。所以這個條件判斷是成立的。

再來看:

	if (!("a" in window)) {
		var a = 1;
	}
	console.log(a);


那這應該是什麼呢?答案是undefined,因為條件不成立,沒有給a賦值成功,預設為undefined 

#

案例二:

	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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn