js解析器:瀏覽器中專門用來讀取js腳本解析和執行步驟: 1)找內容——根據關鍵詞:var function 參數,全部找到之後預解析結束 a = <!--undefined--> 1//所有變數在正式運行之前,都會提前賦值undefined fn = funciong fn(){ console. ...
js解析器:瀏覽器中專門用來讀取js腳本
解析和執行步驟:
1)找內容——根據關鍵詞:var function 參數,全部找到之後預解析結束
a = <!--undefined--> 1//所有變數在正式運行之前,都會提前賦值undefined
fn = funciong fn(){ console.log(a);} //所有的函數,在正式運行之前,都是一個完整的代碼塊
這個過程叫js的預解析
2)逐行解析代碼
正式讀取代碼時,會先從之前解析庫中查找
例1:
1 console.log(a);//undefined 2 var a = 1; 3 console.log(a);//1 4 function fn(){ 5 console.log(a);//1 6 } 7 fn();
1)預解析:
找內容,
1行沒有,
2行有var,給a賦undefined,
3行沒有,
4行有function,函數名為fn,所以fn = function fn() { console.log(a);};原樣保留下來
第5、6、7行沒有,解析完成
所有變數在正式運行之前都會提前賦值undefined
所有函數在正式運行之前都是一個完整的代碼塊,
這個過程叫js的預解析
2)逐行執行代碼
正式讀取代碼時,會先從上一步的解析庫中查找,所以,
1行,a是undefined,
2行重新給a賦值,
3行是1
4行是函數,這個完整的代碼塊也要先解析,調用時再執行
例2:
1 console.log(a);//function a(){ console.log(4);} 2 var a = 1; //表達式可以修改預解析的值 3 console.log(a);//1 4 function a(){ console.log(2);} 5 console.log(a);//1 6 var a = 3;//變數名和函數名重名,只留下函數 7 console.log(a);//3 8 function a(){ console.log(4);} 9 console.log(a);//3 10 console.log(typeof a);//number 11 a();//相當於 3() 報錯
預解析:
1 無
2 a = undefined
3 無
4 由於函數名和變數重名,只留函數 a = undefined被刪除, a = function a(){console.log(2)};
5 無
6 變數名和函數名重名,只留下函數
7 無
8 a = function a(){console.log(2)};被刪除 所以a = function a(){ console.log(4);}
預解析結束,最終庫中留下來的是 a = function a(){ console.log(4);}
逐行執行代碼;
1 //function a(){ console.log(4);}
2 表達式可以修改預解析的值
3 //1
4 不執行
5 //1
6 修改值a=3
7 //3
8 不執行
9 //3
10 //number
例3
1 var a = 1;//全局變數(全局函數):直接在script標簽下,函數外聲明 2 function fn(){ 3 console.log(a);//undefined 4 var a = 2;//局部變數(局部函數):函數內部定義的,只能在函數內部訪問 5 } 6 fn();//一旦函數調用就開始一個新的作用域 7 console.log(a);//1
預解析:
1 a = undefined
2 fn = function fn(){ console.log(a); var a = 2;}
逐條執行代碼:
1 a=1把 a = undefined覆蓋掉
6 一旦調用函數就相當於重新開始一個作用域,再開一個庫
重新解析:
第4行,a = undefined,解析完成,
開始運行,
第3行,運行結果就是undefined
第4行,a = 2;(這是局部作用域中的,此時全局中的a=1)
所以第7行運行結果為1
如果第四行沒有var 只是 a = 2;那麼輸出結果第3行為1,第7行為2
這就涉及到了作用域鏈:父級和子集之間像一個鏈條,在函數中找不到,返回到父元素中去找,父元素中也找不到順著鏈條再向上查找——由內到外
例4:
帶參的函數
1 var a = 1; 2 function fn(a){ //var a = 3 3 console.log(a); 4 var a = 2; 5 console.log(a); 6 } 7 fn();//undefined 2 8 //fn(3);//3 2 9 console.log(a);//1
預解析:a = undefined; fn = function fn(a){ alert(a); var a = 2; alert(a);}
7行 調用函數,在函數中 第2行形參相當於var了一個a,所以a = undefined,第4行a = undefined,(覆蓋掉2行的)
執行代碼:第7行的調用函數輸出是undefined 2
第8行的調用函數輸出是3 2
第9行輸出1用的是外部的a