1.JS解析步驟: a.預解析 將變數聲明提升; 將函數聲明及函數內容提升,可以理解成原來位置的函數在解析代碼時已經提到代碼初始位置; 遇到重名,只留下一個; 如有重名變數和函數,留下函數; 如有兩個重名函數,後一個函數覆蓋前一個函數; firefox不能預解析塊內定義的函數,出於相容性考慮,定義函 ...
1.JS解析步驟:
a.預解析
將變數聲明提升;
將函數聲明及函數內容提升,可以理解成原來位置的函數在解析代碼時已經提到代碼初始位置;
遇到重名,只留下一個;
如有重名變數和函數,留下函數;
如有兩個重名函數,後一個函數覆蓋前一個函數;
firefox不能預解析塊內定義的函數,出於相容性考慮,定義函數,一般要放到最外面
(註意:變數提升的是聲明,函數提升的是聲明和內容)
b.逐行解析代碼
遇到表達式,可以修改預解析的變數值,例如變數賦值可以將函數聲明替換掉;
2.如果有幾個script代碼部分,JS會按照先後順序逐個解析執行,但是這幾個代碼部分共用一個域
3.函數的參數相當於在函數內部定義了這個變數,相當於局部變數,在函數內部解析時也會進行聲明提升
4.JS中,每個函數都有自己的執行環境(作用域),其中使用的變數會按照作用域鏈進行搜索,一直到全局環境,並且只會對目標變數所處的環境造成影響
5.被花括弧包圍的代碼塊在很多類c語言中會有塊級作用域,JS沒有塊級作用域
6.函數傳參相當於賦值表達式
7.只要是一個執行環境(作用域),就會發生JS解析兩個步驟
8.只有函數可以創建局部作用域,如果需要一個類似塊級作用域的作用域,可以在塊內加入一個函數
例子:
alert(a); // function a (){ alert(4); }
var a = 1;
alert(a); // 1
function a (){ alert(2);
alert(a); // 1
var a = 3;
alert(a); // 3
function a (){ alert(4); }
alert(a); // 3
alert( typeof a );
a(); // 報錯
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<script>
alert(a); //報錯
</script>
<script>
var a=1;
</script>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<script>
var a=1
</script>
<script>
alert(a); //1
</script>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var a = 1;
function fn1(){
alert(a); // undefined
var a = 2;
}
fn1();
alert(a); // 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var a = 1;
function fn1(){
alert(a); // 1
a = 2;
}
fn1();
alert(a); // 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var a = 1;
function fn1(a){
alert(a); // undefined
a = 2;
}
fn1();
alert(a); // 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var a = 1;
function fn1(a){
alert(a); // 1
a = 2;
}
fn1(a);
alert(a); // 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
window.onload = function (){
var aBtn = document.getElementsByTagName('input');
for( var i=0; i<aBtn.length; i++ ){
aBtn[i].onclick = function (){
// alert( i ); // Undefined
for( var i=0; i<aBtn.length; i++ ){
aBtn[i].style.background = 'yellow';
}
};
}
};