arguments、arguments.callee、arguments.caller的關(guān)系和區(qū)別
看高三教程的時(shí)候(P177),一段代碼中用到了arguments.callee來調(diào)用函數(shù)自生,書中介紹到 “是一個(gè)指向正在執(zhí)行的函數(shù)的指針,可以用它來實(shí)現(xiàn)對函數(shù)的遞歸調(diào)用。”
這段遞歸調(diào)用代碼如下:
function factorial (num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
var num = factorial(10);
console.log(num); // => 3628800
很簡單的一段代碼。于是自己為了搞清楚知識點(diǎn),加強(qiáng)自身JS基礎(chǔ),就自己查了下文檔
- arguments
- arguments.callee
- arguments.caller
三者的關(guān)系與區(qū)別:
arguments:
在函數(shù)調(diào)用時(shí), 會自動在該函數(shù)內(nèi)部生成一個(gè)名為 arguments的隱藏對象。 該對象類似于數(shù)組, 但又不是數(shù)組。可以使用[]操作符獲取函數(shù)調(diào)用時(shí)傳遞的實(shí)參。
arguments對象不是一個(gè) Array 。它類似于數(shù)組,但除了 長度之外沒有任何數(shù)組屬性。
沒錯(cuò)它是個(gè)對象!并且它存儲的是實(shí)際傳遞給函數(shù)的參數(shù)
function obj(){
//利用instanceof判斷arguments
console.log( 'arguments instanceof Array? ' + (arguments instanceof Array) ); // => false
console.log( 'arguments instanceof Object? ' + (arguments instanceof Object) ); // => true
console.log(arguments); // => []內(nèi)有很多屬性其中包括 callee
}
obj();
(function () {
alert(arguments instanceof Array); // => false
alert(typeof(arguments)); // => object
})();
By The Way:
typeof 是一元運(yùn)算符,返回值為字符串,該字符串用來說明運(yùn)算數(shù)的數(shù)據(jù)類型
用來獲取運(yùn)算數(shù)的數(shù)據(jù)類型。返回的值有number、boolean、undefined、function、object、string
instanceof 用于判斷某個(gè)變量是否是某個(gè)對象的實(shí)例,返回值為true或false
接下來,我們修改上面的代碼,在調(diào)用obj函數(shù)時(shí),給它傳遞參數(shù),但obj函數(shù)自己卻是沒有參數(shù)的。
function obj(){
console.log( 'arguments instanceof Array? ' + (arguments instanceof Array) );
console.log( 'arguments instanceof Object? ' + (arguments instanceof Object) );
console.log(arguments);
}
//向obj傳遞參數(shù)
obj('monkey','love',24);
// => [3]
// 0: "monkey"
// 1: "love"
// 2: "24"
所以我們說為什么 arguments 是存儲的實(shí)際傳遞給函數(shù)的參數(shù)呢,而不是函數(shù)聲明的參數(shù)。
只有函數(shù)被調(diào)用時(shí),arguments對象才會創(chuàng)建,未調(diào)用時(shí)其值為null:
caller 是?
在一個(gè)函數(shù)A 調(diào)用另一個(gè)函數(shù)B時(shí),被調(diào)用函數(shù)B會自動生成一個(gè)caller屬性,指向調(diào)用它的函數(shù)對象即函數(shù)A。如果該函數(shù)A當(dāng)前未被調(diào)用,則caller為null。
function testCaller() {
var caller = testCaller.caller;
alert(caller);
}
function aCaller() {
testCaller();
}
aCaller();
// 最終結(jié)果輸出 => function aCaller() {
// testCaller();
// } 主調(diào)函數(shù)自己
callee 是?
callee是arguments對象的一個(gè)成員,它的值為“正被執(zhí)行的Function對象”。就像第一個(gè)demo的代碼所顯示的一樣
function aCallee(arg) {
alert(arguments.callee);
}
function aCaller(arg1, arg2) {
aCallee();
}
aCaller();
// 最終結(jié)果輸出 => function aCallee(arg) {
// alert(arguments.callee);
// }