天天看點

JavaScript執行環境及作用域執行環境作用域作用域鍊延長作用域鍊

執行環境

  • 執行環境定義了變量或函數有權通路的其他資料,決定了它們各自的行為。
  • 每個函數都有自己的執行環境。當執行流進入一個函數時,函數的環境就會被推入一個環境棧中。而在函數執行之後,棧将其環境彈出,把控制權傳回給之前的執行環境。
  • 在Web浏覽器中,全局執行環境被認為是window對象,是以所有全局變量和函數都是作為window對象的屬性和方法建立的。

執行個體代碼:

//1、頁面載入全局執行環境
	var color = "blue";
	
	function changecolor() {
		// 3、進入changecolor的執行環境
 		var anothercolor = "red";
		 function swapcolors() {
		 	//5、進入swapcolors的執行環境
		 	var tempcolor = anothercolor;
  			anothercolor = color;
  			color = tempcolor; 
		 }
		 
		//4、 執行swapcolors()
		 swapcolors();
	}
	//2、執行changecolor()
	changecolor();
           

各個函數的執行環境示意圖如下

JavaScript執行環境及作用域執行環境作用域作用域鍊延長作用域鍊

作用域

  • 在 JavaScript 中, 作用域為可通路變量,對象,函數的集合。
  • 變量在函數内聲明,變量為局部作用域,隻能在函數内部通路,函數執行完畢後即銷毀。
  • 變量在函數外定義,即為全局變量,網頁中所有腳本和函數均可使用,在頁面關閉後銷毀
  • 在 HTML 中, 全局變量是 window 對象,所有資料變量都屬于 window 對象。
  • 與其他類c語言不同,JavaScript沒有塊級作用域,它使用函數作用域,例:
//對于有塊級作用域的語言來說,for語句初始化變量的表達式所定義的變量,隻會存在與循環的環境之中
	//而對于JavaScript來說,由for語句建立的變量i即使在for循環執行結束後,也依舊會存在于循環内部的執行環境中,直到函數結束
	for(var i=0;i<10;i++){
		doSomething(i)
	}
	alert(i);
           

·

作用域鍊

  • 内部環境可以通過作用域鍊通路所有的外部環境,但外部環境不能通路内部變量環境中的任何變量和函數
  • 當代碼在一個環境中執行時,都會建立一個作用域鍊。 作用域鍊的用途是保證對執行環境有權通路的所有變量和函數的有序通路。
  • 在作用域最前端的是活動對象,而最後端是全局執行環境window(浏覽器宿主中);變量通路原則是,根據作用域前端往上進行搜尋,如果提前搜尋到變量,則停止搜尋
    JavaScript執行環境及作用域執行環境作用域作用域鍊延長作用域鍊
    執行個體代碼:
//全局環境
	var color="blue";
	function changecolor(){
		//changecolor執行環境
 		var anothercolor="red";
 		function swapcolors(){
 			//swapcolors執行環境
 			var tempcolor=anothercolor;
 			anothercolor=color;
 			color=tempcolor;

			//這裡能通路tempcolor,anothercolor,color
  		}
  		//這裡能通路anothercolor,color,但不能通路tempcolor
 		swapcolors();
	}
	//這裡隻能通路color;
	changecolor();
 	
           

下圖形象地展示了上面例子的作用域鍊,其中,内部環境可以通過作用域鍊通路所有外部環境,但外部環境不能通路内部環境中任何變量和函數。

JavaScript執行環境及作用域執行環境作用域作用域鍊延長作用域鍊

·

延長作用域鍊

雖然執行環境的類型總共隻有兩種——全局和局部(函數)。但還是可以通過其他方法來延長作用域鍊。因為有些語句在作用域鍊的前端臨時增加了一個變量對象,該變量對象會在代碼執行後被移除。當執行流進入下列任一語句時,作用域鍊就會得到加長:

  • try-catch語句的catch塊
  • with語句

with語句

with語句的作用是将代碼的作用域設定到一個特定的作用域中

基本文法

with (expression) statement;

例子:

var qs = location.search.substring(1);
	var hostName = location.hostname;
	var url = location.href;
	
	//這幾行代碼都是通路location對象中的屬性,如果使用with關鍵字的話,可以簡化代碼
	with (location){
  		var qs = search.substring(1);
 		var hostName = hostname;
  		var url = href;
	}
           

在這段代碼中,使用了with語句關聯了location對象,這就以為着在with代碼塊内部,每個變量首先被認為是一個局部變量,如果局部變量與location對象的某個屬性同名,則這個局部變量會指向location對象屬性。

注意

在嚴格模式下不能使用with語句。

缺點

  1. 性能問題
  2. 語義不明,調試困難

繼續閱讀