先說幾個概念: 1、js代碼從上往下執行 2、變數提升: 變數提升是瀏覽器的一個功能,在運行js代碼之前,瀏覽器會給js一個全局作用域叫window,window分兩個模塊,一個叫記憶體模塊,一個叫運行模塊,記憶體模塊找到當前作用域下的所有帶var和function的關鍵字,執行模塊執行js代碼,從上到 ...
先說幾個概念:
1、js代碼從上往下執行
2、變數提升:
變數提升是瀏覽器的一個功能,在運行js代碼之前,瀏覽器會給js一個全局作用域叫window,window分兩個模塊,一個叫記憶體模塊,一個叫運行模塊,記憶體模塊找到當前作用域下的所有帶var和function的關鍵字,執行模塊執行js代碼,從上到下執行,遇到變數就會通過記憶體地址去查找這個變數,有和沒有這個變數。有這個變數就會看賦值沒賦值,如果賦值就是後面的值,如果沒有賦值就是undefined,如果沒有找到就說這個變數 is not defined。
3、作用域鏈:
當函數內部的變數被使用時,首先會在自己的私有作用域下查找是否有這個變數,如果有就使用,如果沒有就會向上一級(父級)查找,父級有就使用父級的,如果沒有就繼續向上一級找,有就使用,沒有就接著往上找,直到window,window有就用,沒有就是is not defined。我們管這種查找機制叫做作用域鏈。
一、簡單的小案例:
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);
註:自調用函數沒有變數提升!