javascript中caller與callee的作用以及用法
這兩個(gè)關(guān)鍵字在平時(shí)編碼中幾乎難以用到,但它們既然存在于javascript語(yǔ)言體系中,那么還是有必要了解下。
caller是javascript函數(shù)類型的一個(gè)屬性,它引用調(diào)用當(dāng)前函數(shù)的函數(shù)
function func() {
alert(func.caller);
}
function func1() {
func();
}
func1();
比如上面的代碼购城, 因?yàn)閒unc函數(shù)是杯func1函數(shù)調(diào)用的, 所以func函數(shù)中對(duì)caller的引用就是func1函數(shù)虐译。如果func函數(shù)直接在頂層的javascript環(huán)境中被調(diào)用瘪板,那么caller將返回null。
我們可以利用caller的特性跟蹤函數(shù)的調(diào)用鏈
function func() {
let caller = func.caller;
while(caller != null) {
console.log(caller.name);
caller = caller.caller;
}
}
function func1() {
func();
}
function func2() {
func1();
}
function func3() {
func2();
}
func3();
以上代碼將func3到func的函數(shù)調(diào)用鏈打印出來(lái)漆诽。
callee則不是函數(shù)對(duì)象的屬性侮攀,它是函數(shù)上下文中arguments對(duì)象的屬性
function func() {
alert(arguments.callee);
}
它引用的是函數(shù)自身峭沦,在上面的代碼中左胞,arguments.callee引用的就是func函數(shù)本身省骂。既然他引用的是函數(shù)本身止吐,那么似乎顯得有點(diǎn)多余蚪腐,當(dāng)我們需要在函數(shù)體內(nèi)使用函數(shù)本身時(shí)箭昵,直接通過(guò)函數(shù)名調(diào)用就可以了,干嘛還要多此一舉的通過(guò)arguments.callee這樣去調(diào)用回季。然而我覺(jué)得callee存在的意義可能是想解耦函數(shù)本身對(duì)函數(shù)名稱的依賴吧家制, 比如說(shuō)在遞歸的環(huán)境下,函數(shù)內(nèi)部通常還要調(diào)用函數(shù)本身泡一, 而調(diào)用函數(shù)本身就免不了硬編碼函數(shù)名稱颤殴, 如果函數(shù)名稱有變化, 那么函數(shù)中的代碼也需要修改鼻忠,使用callee就可以避免此類情況涵但。
function factorial( num ) {
if( num == 1 ) {
return 1;
}
let result = num * factorial(num - 1);
return result;
}
alert(factorial(100));
上面的階乘函數(shù)通過(guò)callee可以改造成
function factorial( num ) {
if( num == 1 ) {
return 1;
}
let result = num * arguments.callee(num - 1);
return result;
}
alert(factorial(100));
如此同樣實(shí)現(xiàn)遞歸, 但是可以做到函數(shù)體不依賴函數(shù)名稱帖蔓。