1. 程式人生 > >事件繫結中的call()方法和apply()方法

事件繫結中的call()方法和apply()方法

今天對於call方法和apply方法有些懵,所以去看了些別人的總結,感覺有了點概念,把一些大佬寫的東西中自己感覺易懂的解釋和經典的案例記錄一下。

定義

call方法:
語法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定義:呼叫一個物件的一個方法,以另一個物件替換當前物件。
說明:
call 方法可以用來代替另一個物件呼叫一個方法。call 方法可將一個函式的物件上下文從初始的上下文改變為由 thisObj 指定的新物件。( 第一個借用別人的函式,第二個借用別人的上下文環境。) 如果沒有提供 thisObj 引數,那麼 Global 物件被用作 thisObj。
用括號的第一個引數來代替this的指向
call() 就是用來讓括號裡的物件 來整合括號外的函式的屬性!可以稱之為繼承!

apply方法:
語法:apply([thisObj[,argArray]])
定義:應用某一物件的一個方法,用另一個物件替換當前物件。
說明:
如果 argArray 不是一個有效的陣列或者不是 arguments 物件,那麼將導致一個 TypeError。
如果沒有提供 argArray 和 thisObj 任何一個引數,那麼 Global 物件將被用作 thisObj, 並且無法被傳遞任何引數

作用相同,只是書寫格式不同

call方法案例

function add(a,b)
{
    alert(a+b);
}
function sub(a,b)
{
    alert(a-b);
}

add.call(sub,3,1);
個人理解call和apply的作用就是切換函式的物件上下文。

“這個例子中的意思就是用 add 來替換 sub“,應該是將add執行的上下文由window切換為sub,即this指向是從window變為sub,僅此而已,並非add替換sub。這個例子很難說明什麼。
其實就是call方法前面的東西(add)都交給後面(sub)了,就像兄弟,接過這把槍。

add.call(sub,3,1) // sub 已經接過了add方法

.function Animal(){    
this.name = "Animal";    
this.showName = function(){    
alert(this.name);    
 }    
}     
.function Cat(){    
 this.name = "Cat";    
}      
var animal = new Animal();    
var cat = new Cat(); 

//通過call或apply方法,將原本屬於Animal物件的showName()方法交給物件cat來使用了。
//輸入結果為"Cat"
//animal.showName.call(cat,",");
//animal.showName.apply(cat,[]);

call 的意思是把 animal 的方法放到cat上執行,原來cat是沒有showName() 方法,現在是把animal 的showName()方法放到 cat上來執行,所以this.name 應該是 Cat。

“call 的意思是把 animal 的方法放到cat上執行”這個應該是animal.showName呼叫時候,將animal中的this物件轉變為cat,alert(this.name);這時候的this是cat,因此this.name==cat.name,所以輸出是Cat。

補充

關於javascript中call和apply函式的應用
我們經常在javascipt中的面向物件應用中遇到call和apply函式;有時會被搞糊塗。其實它們可以改變函式或物件中的this保留字的值;this保留字的預設值就是這個類本身。舉例說明:
複製程式碼 程式碼如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
<script language="javascript"> 
test = { 
value: 'default',exec: function() { 
alert(this.value); 
} 
} 
function hhh(obj) { 
test.exec();test.exec.apply(obj); 
} 
</script> 
</head> 
<body> 
<input type="button" onclick="hhh(this);" value="test" /> 
</body> 
</html> 

執行以上的頁面就很快明白了. 
call和apply函式可以處理匿名函式 
關於類的初始化應用如下: 
複製程式碼 程式碼如下:

Person = function() { 
this.Init.apply(this, arguments); 
}; 
Person.prototype = { 
first: null, 
last: null, 
Init: function(first, last) { 
this.first = first; 
this.last = last; 
}, 
fullName: function() { 
return this.first + ' ' + this.last; 
}, 
fullNameReversed: function() { 
return this.last + ', ' + this.first; 
} 
}; 
var s = new Person2('creese', 'yang'); 
alert(s.fullName()); 
alert(s.fullNameReversed()); 

call和apply函式可以賦值函式內容(帶匿名引數;但不觸發)
關於函式繫結事件應用如下:
複製程式碼 程式碼如下:

Function.prototype.BindForEvent = function() { 
var __m = this, object = arguments[0], args = new Array(); 
for(var i = 1; i < arguments.length; i++){ 
args.push(arguments[i]); 
} 
return function(event) { 
return __m.apply(object, [( event || window.event)].concat(args)); 
} 
} 

call和apply函式關於函式繫結引數應用如下:
複製程式碼 程式碼如下:

Function.prototype.Bind = function() { 
var __m = this, object = arguments[0], args = new Array(); 
for(var i = 1; i < arguments.length; i++){ 
args.push(arguments[i]); 
} 
return function() { 
return __m.apply(object, args); 
} 
} 

call和apply函式功能是一樣的;就是引數格式不同;fun.call(obj, arguments);apply的arguments是陣列形式;call則是單數形式。