function的執行依賴於變數的作用域,這個作用域是在function定義時決定,並不是在被呼叫時決定的。
function物件內部包含代碼邏輯外,還必須引用當前作用域鏈,function可透過作用域鏈相互連接起來,function內部的變量都可以保存在function作用域內。
var scope= "global"
function fn(){
var scope= "local"
function fn_1(){return scope;}
return fn_1;
}
fn()(); // "local"
// 等同
var call_fn= fn(); // call_fn = fn_1
call_fn(); // 執行fn_1();
可以看出上面兩段程式碼,一個是直接回覆fn計算完的結果(在fn裡面執行fn_1),另一個是在fn外執行fn_1,但最後顯示的訊息都是一樣的。
function counter(n){ n 為函式內私有變數
return{
get count(){return n++;},
set count(m){ n = m ;}
}
}
var c = counter(10);
c.count // return 10
c.count // return 11
c.count = 1000 // 此時counter裡面的n為1000
c.count // 1000
下面兩個例子
function fn_a(v){
return function() {return v;}
}
var ary_a =[];
for(var i = 0 ; i<10 ; i++){
ary[i] = fn_a(i);
}
// 上述的for迴圈執行完後
// ary[0] = function() {return 0;}
// ary[1] = function() {return 1;}
// ...
ary[5]() // 5
function fn_b(v){
var ary_b =[];
for(var j = 0 ; j<10 ; j++){
ary_b[j] = function (){ return j; }
}
return ary_b;
}
// 上面的程式碼等同於
// function fn_b(v){
// var ary =[];
// var i;
// for(i = 0 ; i<10 ; i++){
// ary[i] = function (){return i;}
// }
// return ary;
// }
var test = fn_b();
test[5]() // 10
i | ary |
---|---|
0 | ary[0] = function(){return i;} |
1 | ary[0] = function(){return i;} |
ary[1] = function(){return i;} | |
2 | ary[0] = function(){return i;} |
ary[1] = function(){return i;} | |
ary[2] = function(){return i;} | |
... | ... |
9 | ary[0] = function(){return i;} |
ary[1] = function(){return i;} | |
ary[2] = function(){return i;} | |
... | |
ary[9] = function(){return i;} // 此時i =10 | |
... | ... |
call()和apply()都是間接的呼叫函式(function)。兩者的第一個引數都是用來定義函式內this要指向誰。
call()和apply()兩者作用大致上是一樣的,僅差在輸入的引數fn.call(this,x,y,z,...)
fn.call(this,[x,y,z,...])
第二個引數為陣列
function fn_a(){
this.name = 'Jackson';
this.id = 1;
}
function fn_b(){
this.name = 'Jack';
this.print = function(){
console.log(this.name + ' is a superman.')
}
}
var b= new fn_b;
b.print(); // Jack is a superman
var a = new fn_a
b.print.call(a); // 將a(第一個引數)傳入即代表在print函式裡頭的this是指向a裡頭的name
// Jackson is a superman.
與call、apply雷同,第一個引數一樣是定義函式內部的this指向。
call() apply()屬於立即函式,但bind()會回傳函式,需要再呼叫才會執行。
var a = {name:'Jackson'}
function fn_c(){
console.log(this.name + ' is a superman!')
}
var cb = fn_c.bind(a);
cb() // "Jackson is a superman! "