js:作用域總結1
先說幾個概念:
1、js程式碼從上往下執行
2、變數提升:
變數提升是瀏覽器的一個功能,在執行js程式碼之前,瀏覽器會給js一個全域性作用域叫window,window分兩個模組,一個叫記憶體模組,一個叫執行模組,記憶體模組找到當前作用域下的所有帶var和function的關鍵字,執行模組執行js程式碼,從上到下執行,遇到變數就會通過記憶體地址去查詢這個變數,有和沒有這個變數。有這個變數就會看賦值沒賦值,如果賦值就是後面的值,如果沒有賦值就是undefined,如果沒有找到就說這個變數 is not defined。
3、作用域鏈:
一、簡單的小案例:
1、
var a = 12;
function fn(){
console.log(a); //undefined
var a = 45;
console.log(a); //45
}
2、
function fn(){
console.log(11);
function ff(){
console.log(22);
}
ff();
}
fn() //11
ff() // ff is not defined
3、
var a = 123;
function fun(){
alert(a) //123
}
fun(); //私有作用域下沒有宣告變數a,就在父級找,有就直接使用。
4、
var a = 123;
function fun(){
alert(a); //123 私有作用域裡並沒有宣告變數a,所以就在父級找,有就直接使用。
a = 456;
}
fun()
alert(a) //456 fun()裡改變了全域性變數a的值
5、
var a = 123;
function fun(a){
alert(a); //undefined 這裡有形參,但是並沒有傳實參
a = 456; //給引數賦值
}
fun();
alert(a) //123 全域性變數a
6、
var a = 123;
function fun(a){
alert(a); //123 這裡傳了固定的引數123
a = 456;
}
fun(123)
alert(a) //123
7、
var a = 12;
function fn(){
console.log(a) //undefined 程式碼從上往下執行,記憶體模組只定義,不賦值。
var a = 45;
console . log(a) //45
}
fn()
8、
function test(a,b){
console . log(b) //function b(){} function關鍵字,在記憶體模組裡面宣告和定義同時進行
console . log(a) //1
c=0;
a=3;
b=2;
console . log(b); //2
function b(){ }
function d(){ }
console . log(b) //2
}
test(1)
9、
function test(a,b){
console . log(a) //function a(){} 覆蓋了實參
console . log(b) //undefined
var b=234;
console . log(b) //234
a=123;
console . log(a) //123
function a(){ }
var a;
b=234;
var b=function (){ }
console . log(a); //123
console . log(b) //function
}
test(1)
二、阿里面試:
var a = 100;
function testResult(){
var b = 2 * a;
var a = 200;
var c = a / 2;
alert(b);
alert(c);
}
三、自呼叫函式:
+function(){
console.log(a);
var a = 5;
function a(){}
console.log(a);
function b(){}
b = 6;
console.log(b);
var c = d = b;
}()
console.log(d);
console.log(c);
注:自呼叫函式沒有變數提升!