js中一個函式中呼叫另一個函式,內部函式怎麼訪問外部函式的變數? 無意中逛到這個問題,突然發現自己以前也有這樣的困惑
function a(){ alert(num); }
function b(){
var num=3;
a();
}
b(); //num is not defined
複製程式碼
a函式不是b的內部函式(閉包),而是全域性函式。所以對於a函式來說,即使你b在內部呼叫了我a,我a還是訪問不了你b。 說到底就是作用域問題,所以我想到了改變作用域的方法
call(),apply(),bind()
實現
function a(){ alert(num); }
function b(){
var num=3;
a.call(b);
}
b(); // num is not defined
複製程式碼
嘗試了很多次,都無法獲取到b,原來我對這些方法理解有誤,查閱文件,發現此類方法主要作用是,物件呼叫不屬於自己的方法,例如下例: food函式是沒有product方法,使用call對food的上下文進行product操作
//mozilla官方用例
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);
複製程式碼
使用閉包
閉包就不多說了,一個函式內部定義(不是呼叫)另一個函式 內部函式可呼叫外部函式的變數,作用域鏈的延長
改寫
function b(){
var num=3;
function a(){ alert(num); }
a();
}
b(); //3
複製程式碼
傳參
function a(num){ alert(num); }
function b(){
var num=3;
a(num);
}
b(); //3
複製程式碼
return
function a(){ alert(b()); }
function b(){
var num=3;
return num;
}
a();
複製程式碼
總結
一般來說,a是複用的函式,才會有此類用法,傳參實現即可。
參考資料
深入淺出妙用 Javascript 中 apply、call、bind 學習Javascript閉包(Closure) call()方法