詞法作用域


詞法作用域

作用域

域表示的就是 范圍, 即 作用范圍. 就是一個名字在什么地方可以被使用, 什么時候不能使用.

塊級作用域

即塊級別的作用范圍

	// 在 C , Java 等編程語言中, 下面的語法報錯
	{
		var num = 123;  // int 
		{
			console.log( num ); // => 123
		}
	}
	console.log( num ); // 報錯

在 js 中采用詞法作用域

所謂的 詞法( 代碼 )作用域, 就是代碼在編寫過程中體現出來的作用范圍. 代碼一旦寫好, 不用執行,
作用范圍就已經確定好了. 這個就是所謂詞法作用域.

在 js 中詞法作用域規則:

  1. 函數允許訪問函數外的數據.
  2. 整個代碼結構中只有函數可以限定作用域.
  3. 作用規則首先使用提升規則分析
  4. 如果當前作用規則中有名字了, 就不考慮外面的名字

作用域鏈

可以發現只有函數可以制造作用域結構. 那么只要是代碼, 至少有一個作用域, 即全局作用域.
凡是代碼中有函數, 那么這個函數就構成另一個作用域. 如果函數中還有函數, 那么再這個作用域中就
又可以誕生一個作用域. 那么將這樣的所有的作用域列出來, 可以有一個結構: 函數內指向函數外的鏈式結構.

繪制作用域鏈的步驟:

  1. 看整個全局是一條鏈, 即頂級鏈, 記為 0 級鏈
  2. 看全局作用域中, 有什么成員聲明, 就以方格的形式繪制到 0 級練上
  3. 再找函數, 只有函數可以限制作用域, 因此從函數中引入新鏈, 標記為 1 級鏈
  4. 然后在每一個 1 級鏈中再次往復剛才的行為

變量的訪問規則

  1. 首先看變量在第幾條鏈上, 在該鏈上看是否有變量的定義與賦值, 如果有直接使用
  2. 如果沒有到上一級鏈上找( n - 1 級鏈 ), 如果有直接用, 停止繼續查找.
  3. 如果還沒有再次往上剛找... 直到全局鏈( 0 級 ), 還沒有就是 is not defined
  4. 注意, 切記 同級的鏈不可混合查找

如何分析代碼

  1. 在分析代碼的時候切記從代碼的運行進度上來分析, 如果代碼給變量賦值了, 一定要標記到圖中
  2. 如果代碼比較復雜, 可以在圖中描述代碼的內容, 有事甚至需要將原型圖與作用域圖合並分析
	var num = 123;
	function f1() {
		console.log( num );
	}
	function f2() {
		var num = 456;
		f1();
	}
	f2();
	var num = 123;
	function f1() {
		console.log( num );
	}
	function f2() {
		num = 456;
		f1();
	}
	f2();

補充

  1. 聲明變量使用 var, 如果不使用 var 聲明的變量就是全局變量( 禁用 )
  2. 因為在任何代碼結構中都可以使用該語法. 那么在代碼維護的時候會有問題. 所以除非特殊原因不要這么用.
  3. 下面的代碼的錯誤
	function foo () {
		var i1 = 1  // 局部
			i2 = 2, // 全局
			i3 = 3; // 全局
		
	}
  1. 此時注意
	var arr = [];
	for ( var i = 0; i < 10; i++ ) {
		arr.push( i );
	}
	for ( var i = 0; i < 10; i++ ) {
		console.log( arr[ i ] );
	}
	// 一般都是將變量的聲明全部放到開始的位置, 避免出現因為提升而造成的錯誤
	var arr = [], 
		i = 0;
	for ( i=0; i < 10; i++ ) {
		arr.push( i );
	}
	for ( i = 0; i < 10; i++ ) {
		console.log( arr[ i ] );
	}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM