\如需轉載請注明來源
1.作用域
- 作用域聲明提前:1 帶var的和函數不管位置在哪里,在作用域中都會被提到最前面進行解析,把變量賦值為undefind。變量>函數是解析順序,把變量賦值undefined,把函數解析成字符串,等號右邊的值要等到JS的線程執行到。2 等號右邊是在運行的時候才能解析得到。
- 作用域鏈:1 作用域訪問未在自身內部定義的變量或者函數,會一層一層往父級以上的作用域找,換句話說只能由內而外。2 作用域鏈的定義與函數自身在哪里運行無關,和函數自身解析的位置才相關。
首先,JS是單線程任務語言,也就是說,JS是從上到下依次解析的。
其次函數才生成作用域,if或者for還有JSON里面的{}不能生成作用域。
根據作用域規則
現在,先讓我們看一個例子。
console.log(a);//undefined
console.log(fn);//function fn(){}
var a=0;
function fn (){ }
第二個例子:
console.log(a)
var a=1
function fn(){
console.log(a)
var a=10;
function fn2(){
a=20;
}
fn2();
console.log(a)
}
fn()
console.log(a)
結果是: 第一個打出的是undefined。因為聲明被提前。第二個是fn的console也是undefined理由同上。第三個:20,按照執行順序來看。第四個是 1,因為fn并沒有引用外部變量。這里最主要的是變量聲明的提前。
讓我們再看一下以下的問題。
console.log(fn);
var fn=function(){ console.log(1);};
console.log(fn);
根據等號后執行,輸出的結果是undefinded,function(){console.log(1)}
根據作用域鏈讓我們再看幾個例子。
var a=0;
function fn1(){
a=10;
function fn2(){
console.log(a);
var b=2;
}
fn2();
console.log(b)
}
fn1();
console.log(a)
輸出依次是:fn2:10,fn1:報錯,全局的conosle:10
解析:首先執行fn2,fn2函數往fn1這個父級函數找到a,所以a=10;第二個console,fn1找不到這個變量,就往全局中尋找,全局也找不到就直接報錯了。第三個console,經過fn1的折騰,此時全局的a已經變成10。