標籤:efi 部分 func name seve define var def 多個參數
ECMAScript3 給Function原型上定義了兩個方法,他們是Function.prototype.call和Function.prototype.apply。
1 var func =function(a,b,c){ 2 alert([a,b,c]); 3 }; 4 func.apply(null,[1,2,3]);//apply 5 6 7 var func =function(a,b,c){ 8 alert([a,b,c]); 9 };10 func.call(null,1,2,3);//call
apply::兩個參數,第一個參數:指定了函數體內this對象的指向;
第二個參數:一個帶下標的集合,可以為數組,也可以為偽數組
call:多個參數:第一個參數:指定了函數體內this對象的指向;
第二個參數開始往後,每一個參數被依次傳入函數;
call和apply傳入的第一個參數為null,函數體內this會指向預設的宿主對象,在瀏覽器中則是window
如果在strict 模式下,函數體內的this還是為null 1 var func = function(a,b,c){
2 alert(this === window);//true 3 }; 4 5 func.apply(null,[1,2,3]) 6 7 var func = function(a,b,c){ 8 "use stract";//如果在strict 模式下,函數體內的this還是為null 9 alert(this === null);//true 10 };11 func.apply(null,[1,2,3]);
1.改變this的指向
1 var obj1 = { 2 name:"seven" 3 }; 4 5 var oj2 = { 6 name:"anne" 7 }; 8 9 window.name = "window";10 11 var getName = function(){12 alert(this.name)13 };14 15 getName();//window16 getName.call(obj1);//seven17 getName.apply(obj2);//anne
View Code
在實際開發中,經常會遇到this指向被不經意改變的情境,比如,有一個div節點,div節點的onclick事件中的this本來指向這個div的:
1 dcument.getElementById("div1").onclick=function(){ 2 alert(this.id);//div1 3 } 4 //加入改時間函數中有一個內建函式func,在實踐內部調用func函數時,func函數體內的this就指向了window,而不是我們預期的div 5 6 document.getElementById("div1").oonclick = function(){ 7 alert(this.id);//div1 8 var func = function(){ 9 alert(this.id) //undefined10 };11 func();12 };13 //這時候我們用call來修正func函數內的this,使其指向div14 document.getElementById("div1").onclick=function(){15 var func = function(){16 alert(this.id);//div117 };18 func.call(this);19 }
使用call來修正this的情境,我們並不是第一次遇到,
1 document.getElementById = (function(){2 return function(){3 return func.apply(document,arguments);4 }5 })(document.getElementById);6 7 var getId =document.getElementById;8 var div = getId("div1");9 alert(div.id); //div1
2.Function.prototype.bind
大部分瀏覽器都實現了內建的Function.prototype.bind,用來指定函數內部的this指向,即使沒有原生的Function.prototype.bind實現。
1 Function.prototype.bind= function(context){ 2 var self = this;//儲存原函數 3 return function(){//返回一個新函數 4 return self.apply(context,arguments);//執行新的函數的時候,會把之前的context當做新函數體內的this 5 }; 6 } 7 8 var obj = { 9 name:"seve"10 };11 12 var a = function(){13 alert(this.name);//seve14 }.bind(obj);15 16 a();
我們通過Function.prototype.bind來“封裝”func函數,並且傳入一個對象context當作參數,這個context對象就是我們想修正的this對象。
在Function.prototype.bind的內部實現中,我們先把func函數的引用儲存起來,然後返回一個新函數。當我們在將來執行a函數時,實際上先執行的是這個剛剛返回的新函數。在新函數內部,self.apply(context,arguments)這句話代碼是執行原來的a函數,並且指定context對象為a函數體內的this.
下面是複雜一點的實現:
js call 和apply