事件繫結中的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則是單數形式。