標籤:函數 while btn ref 聲明 read 未定義 undefined 函數調用
【js預解析機制】
先來說說js的解析機制吧,瀏覽器在解析js代碼時是從上到下解析的。
解析順序如:
(1)預解析
找var和function
(2)逐行代碼解析
運算式
函數調用
fn1()函數內部再發生
{
(1)預解析
(2)逐行代碼解析
}
解析:
由子級到父級尋找變數,稱範圍鏈
如:函數參數,為局部變數
<script type="text/javascript"> var a=1; function fn1(a){//把a作為參數傳進來,但是並沒有在他的局部範圍定義 console.log(a);//函數內預解析為a=undefined a=2;//後又將a改為2 } fn1(); console.log(a);//輸出1,在全域中找到的a=1</script>
如:
<script type="text/javascript"> var a=1; function fn1(a){ console.log(a);//輸出1 a=2; } fn1(a); //傳的參數為var a=1;為局部的 console.log(a);//輸出1,此1為全域var a=1;</script>
【js預解析器】通俗的講就是在瀏覽器解析js代碼前,他的預解析器會首先找到一些變數或把代碼中的一些變數放入自己的倉庫,在進行解析。
如:
預解析:
找一些東西:var、 function、 參數、a=未定義
所有變數,在正式運行代碼之前,都提前賦一個值:未定義undefined
fn1=function fn1(){alert(2);} //所有的函數,在正式運行代碼之前都是整個函數塊
注意:遇到重名,變數和函數重名,就留下函數,與上下關係沒有關係,注:只先找var ,function聲明的,
如:
console.log(a); var a=1; console.log(a); function a(){console.log(2);} console.log(a); var a=3; console.log(a); function a(){console.log(4);} console.log(a);
具體過程:
1.找到第一個var存值為undefined(注意不會為其賦值為1,而是undefined)
2.function a(){console.log(2);}代替前面var
3.var =3不會替代function
4.function a(){console.log(4);}替代function a(){console.log(2);}
5.預解析結果:把a=function a(){console.log(4);}存在預解析的倉庫裡面
(2)逐行解讀代碼
運算式= + - / ++ -- !參數等,(一個動作能夠去做一些改變
)
如:
alert(a);undefinedvar a=1;alert(a);//1
運算式可以預解析該倉庫裡面的值
而function a(){alert(2);}只是一個聲明並不會改變a的值
逐行解讀代碼的結果:
console.log(a);//function a(){console.log(4);} var a=1; console.log(a);//1 function a(){console.log(2);} console.log(a);//1 var a=3; console.log(a);//3 function a(){console.log(4);} console.log(a);//3//最後存在倉庫裡面的就是a=3一個數字
如:利用局部改全域
var str=""; function fn1(){ var a=‘哈哈哈~‘; str=a; } fn1(); //console.log(a);//Uncaught ReferenceError: a is not defined console.log(str);//哈哈哈~,利用局部改全域
如:函數內部調用外部函數:
function fn2(){ var a=‘這是fn2的東西!‘; fn3(a); } fn2(); function fn3(b){ console.log(b);//註:與fn2裡面的a不一樣,輸出為這是"fn2的東西!"}
註:
if(){}
for(){} while()
不是範圍
註:
<script type="text/javascript"> window.onload=function(){ var Btn=document.getElementsByTagName(‘input‘); var i=0; for(i=0;i<Btn.length;i++){ Btn[i].onclick=function(){ for(i=0;i<Btn.length;i++){ Btn[i].style.background=‘red‘;//如果沒有下面的for會出現Uncaught TypeError: Cannot read property ‘style‘ of undefined } } } };</script>
JS解析+預解析相關總結