1. 程式人生 > >js 作用域

js 作用域

ebe ring 根據 ole 如果 cti def scrip 是我

script不能分割作用域,但是會對每個script標簽對預編譯,如代碼3

代碼1:

<script>
    console.log(typeof a2)//undefined
    var a2=‘littlebear‘;
    console.log(a2)//littlebear
</script>
<script>
    console.log(typeof a2)//string
    var a2=1;
    console.log(a2)//1
</script>

代碼2:

<script>
    console.log(
typeof a2)//undefined var a2=‘littlebear‘; console.log(a2)//littlebear console.log(typeof a2)//string var a2=1; console.log(a2)//1 </script>

代碼3:

<script>
    console.log(typeof a)//undefined
    console.log(a)//報錯,遇到<script>標簽對時,會先對這一塊進行預解析,下面沒預解析,所以找不到聲明過的a,於是報錯了
</script>
<script>
    console.log(
typeof a)//undefined var a=1; console.log(a)//1 </script>

第一個script標簽裏的a,undefined,直接輸出啊,立馬報錯。因為在第一個script標簽的時候沒有發現a聲明過,沒聲明直接使用就會報錯。 第二個script標簽裏面的輸出是我們預料之中的

得出一個結論:js的預編譯,是從有順序的,根據script標簽的順序從上到下執行的。

預編譯階段會預編譯var後面的變量,函數參數、函數

例如:

<script>
    function fn(a,b){
        console.log(a)
//容易上當 var a=10; console.log(a)//10 } fn(‘容易上當‘); </script>

函數,函數參數,var聲明的變量在一起的時候

<script>
    var a=10;
    function fn(a,b){
        console.log(a)//function a(){}   這裏輸出function a(){}, 不是參數a的值,哈哈
        var a=10;
        console.log(a)//10
        function a(){}
        console.log(a)//10
    }
    fn(15);
</script>

參數a會覆蓋預編譯變量a的默認值,如果有函數,函數會覆蓋參數a的值,這個就是先後順序而已

return 和函數、var聲明的變量在一起的時候

<script>
    function fn(){
        function a(){console.log(1)}
        return a;
        function a(){console.log(2)}
    }
    fn()();//2
</script>

由於預編譯,後面的a覆蓋了前面的a,所以return a的值 其實就是預編譯之後a的值,預編譯之後a的值就是第二個a。

 var a=10;
    function fn(){
        //預編譯a 賦值undefined,內部作用域存在a這個變量,所以這裏 !a 就是  !undefined,就是true,進入函數a=20;
        //但是後面的a怎麽就是20呢,js沒有塊級作用域!! 不要小看js各種細節,夠折騰的
        if (!a) {
            var a=20
        }
        console.log(a)//  這裏是20 ,
    }
    fn()

  //a in window ==>true 、 !true ===》false
    if (!(a in window)) {
        var a = 1;
    }
    console.log(a)// undefined

 

js 作用域