JScript參考中說明為:返回一個對函數的引用,該函數調用了當前函數。
如何理解這句話, 先來舉個簡單的例子:
// caller demo {
function callerDemo() {
if (callerDemo.caller) {
var a= callerDemo.caller.toString();
alert(a);
} else {
alert("this is a top function");
}
}
function handleCaller() {
callerDemo();
}
上面的例子,可以看出,它就是返回一個調用數據的引用。(指向請求調用的函數) 也由此可以看出,當在這樣的情況下,onclick觸發事件的時候總是帶著匿名函數的
2、callee
JScript參考中的說明為:返回正被執行的 Function 對象,也就是所指定的 Function 對象的正文。
需要注意的是callee擁有length屬性,這個在有的時候用於驗證還是比較好的。
function calleeDemo() {
alert(arguments.callee);
}
function calleeLengthDemo(arg1, arg2) {
if (arguments.length==arguments.callee.length) {
window.alert("驗證形參和實參長度正確!");
return;
} else {
alert("實參長度:" +arguments.length);
alert("形參長度: " +arguments.callee.length);
}
}
從上面的例子可以看出,callee可以用來打在執行函數,也就是指向被調用的函數。上面的例子就說明calee可以打印其本身,當然還有其它的一些用途。而length屬性中arguments.length是實參長度,arguments.callee.length是形參長度,由此可以判斷調用時形參長度是否和實參長度一致。
3、call 和 apply
call方法JScript參考中的說明:調用一個對象的一個方法,以另一個對象替換當前對象。call([thisObj[,arg1[, arg2[, [,.argN]]]]]),但是沒有示例
apply方法JScript參考中的說明:應用某一對象的一個方法,用另一個對象替換當前對象。apply([thisObj[,argArray]])
實際上這兩個的作用幾乎是相同的,要注意的地方是call(thisObj[,arg1[, arg2[,)中的arg參數可以是變量,而apply([thisObj[,argArray]])中的參數為數組集合。下面來看看call, apply的具體應用
// simple call demo
function simpleCallDemo(arg) {
window.alert(arg);
}
function handleSPC(arg) {
simpleCallDemo.call(this, arg);
}
// simple apply demo
function simpleApplyDemo(arg) {
window.alert(arg);
}
function handleSPA(arg) {
simpleApplyDemo.apply(this, arguments);
}
從上面簡單的例子可以看出,call和apply可以把當前的參數傳遞給另外一個函數的參數中,從而調用另一個函數的應用。有的時候這是一個很實用的方法,當然,用call或是apply(是參數或是數組),看實際情況而定了。
下面來看另一個應用
call和apply還有一個技巧在裡面,就是用call和apply應用另一個函數(類)以後,當前的函數(類)就具備了另一個函數(類)的方法或者是屬性,這也可以稱之為"繼承"。看下面示例。
// inherit
function base() {
this.member = "never-online";
this.method = function() {
window.alert(this.member);
}
}
function extend() {
base.call(this);
window.alert(member);
window.alert(this.method);
}
上面的例子可以看出,通過call之後,extend可以繼承到base的方法和屬性。
再看一個apply的應用
// advanced apply demo
function adApplyDemo(x) {
return ("this is never-online, BlueDestiny '" + x + "' demo");
}
function handleAdApplyDemo(obj, fname, before) {
var oldFunc = obj[fname];
obj[fname] = function() {
return oldFunc.apply(this, before(arguments));
};
}
function hellowordFunc(args) {
args[0] = "hello " + args[0];
return args;
}
function applyBefore() {
alert(adApplyDemo("world"));
}
function applyAfter() {
handleAdApplyDemo(this, "adApplyDemo", hellowordFunc);
alert(adApplyDemo("world")); // Hello world!
}
需要注意的是,要先點"原始的adApplyDemo('world')"按鈕,如果先點"應用後的adApplyDemo('world')"按扭,會先應用了apply方法,這樣原始的值將會被改變。或許有的朋友沒有發現有什麼特別的,我在這裡指明一下,當點擊左邊的按扭時,只有"this is never-online, BlueDestiny 'world' demo", 當點擊右邊的按扭後,會現結果是"this is never-online, BlueDestiny 'hello world' demo",再點點左邊的按扭,看看結果又會是什麼呢?自己試試看:D,已經改寫了函數adApplyDemo。這個例子則說明了call和apply的"真正"作用了。
Power By BlueDestiny, never-online,
http://www.never-online.net