*概述
本文将说明函数相关的几个属性的含义,内容如下
---每个javascript函数有arguments和caller属性,记作F.arguments,F.caller(F表示函数名称);
---arguments有length和callee两个属性;
*属性含义
---F.arguments
1)包含传递给函数的参数对象,可以通过'[]运算'获取函数的参数;
2)具有length属性,表示函数参数的个数;
---F.caller
表示当前函数被哪个函数调用;
例如下面的示例中函数fun2中执行函数fun1,那么fun1.caller的值就是fun2;
通过这个属性的值, 可以获取函数的调用栈
---arguments.length
表示传递给arguments的参数个数
---arguments.callee
表示当前函数自身;
例如,下面的函数fun1,fun1.arguments.callee == fun1;
这个属性经常在new对象时, 用于修改对象的constructor属性, 让其值为函数自身.
*示例,演示了函数属性的取值
---源码(下载)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 function fun1(){ 2 console.log("run " + arguments.callee); 3 console.log("arguments is array: " + (arguments instanceof Array)); //false 4 console.log("arguments.length: " + arguments.length); 5 if(arguments.length > 0) 6 console.log("arguments[0]: " + arguments[0]); 7 console.log("arguments.callee: " + arguments.callee); 8 console.log("arguments.callee.caller: " + arguments.callee.caller); 9 console.log("\n"); 10 } 11 12 function fun2(){ 13 console.log("run " + arguments.callee); 14 console.log("arguments is array: " + (arguments instanceof Array)); //false 15 console.log("arguments.length: " + arguments.length); 16 console.log("arguments.callee: " + arguments.callee); 17 console.log("arguments.callee.caller: " + arguments.callee.caller); 18 console.log("\n") 19 20 fun1(1); 21 } 22 23 fun1(); 24 fun2(); 25 26 console.log("host"); 27 if(arguments){ 28 console.log("host arguments.length: " + arguments.length); 29 console.log("host arguments.callee: " + arguments.callee); 30 console.log("host arguments.callee.caller: " + arguments.caller); //undefined 31 }
---结果(测试环境为Node)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 dzh@dzh-laptop:~/lx/js/example$ node t_func.js //开始执行 2 run function fun1(){ //运行fun1() 3 console.log("run " + arguments.callee); 4 console.log("arguments is array: " + (arguments instanceof Array)); //false 5 console.log("arguments.length: " + arguments.length); 6 if(arguments.length > 0) 7 console.log("arguments[0]: " + arguments[0]); 8 console.log("arguments.callee: " + arguments.callee); 9 console.log("arguments.callee.caller: " + arguments.callee.caller); 10 console.log("\n"); 11 } 12 arguments is array: false 13 arguments.length: 0 14 arguments.callee: function fun1(){ 15 console.log("run " + arguments.callee); 16 console.log("arguments is array: " + (arguments instanceof Array)); //false 17 console.log("arguments.length: " + arguments.length); 18 if(arguments.length > 0) 19 console.log("arguments[0]: " + arguments[0]); 20 console.log("arguments.callee: " + arguments.callee); 21 console.log("arguments.callee.caller: " + arguments.callee.caller); 22 console.log("\n"); 23 } 24 arguments.callee.caller: function (exports, require, module, __filename, __dirname) { function fun1(){ 25 console.log("run " + arguments.callee); 26 console.log("arguments is array: " + (arguments instanceof Array)); //false 27 console.log("arguments.length: " + arguments.length); 28 if(arguments.length > 0) 29 console.log("arguments[0]: " + arguments[0]); 30 console.log("arguments.callee: " + arguments.callee); 31 console.log("arguments.callee.caller: " + arguments.callee.caller); 32 console.log("\n"); 33 } 34 35 function fun2(){ 36 console.log("run " + arguments.callee); 37 console.log("arguments is array: " + (arguments instanceof Array)); //false 38 console.log("arguments.length: " + arguments.length); 39 console.log("arguments.callee: " + arguments.callee); 40 console.log("arguments.callee.caller: " + arguments.callee.caller); 41 console.log("\n") 42 43 fun1(1); 44 } 45 46 fun1(); 47 fun2(); 48 49 console.log("host"); 50 if(arguments){ 51 console.log("host arguments.length: " + arguments.length); 52 console.log("host arguments.callee: " + arguments.callee); 53 console.log("host arguments.callee.caller: " + arguments.caller); //undefined 54 } 55 } 56 57 58 run function fun2(){ //运行fun2() 59 console.log("run " + arguments.callee); 60 console.log("arguments is array: " + (arguments instanceof Array)); //false 61 console.log("arguments.length: " + arguments.length); 62 console.log("arguments.callee: " + arguments.callee); 63 console.log("arguments.callee.caller: " + arguments.callee.caller); 64 console.log("\n") 65 66 fun1(1); 67 } 68 arguments is array: false 69 arguments.length: 0 70 arguments.callee: function fun2(){ 71 console.log("run " + arguments.callee); 72 console.log("arguments is array: " + (arguments instanceof Array)); //false 73 console.log("arguments.length: " + arguments.length); 74 console.log("arguments.callee: " + arguments.callee); 75 console.log("arguments.callee.caller: " + arguments.callee.caller); 76 console.log("\n") 77 78 fun1(1); 79 } 80 arguments.callee.caller: function (exports, require, module, __filename, __dirname) { function fun1(){ 81 console.log("run " + arguments.callee); 82 console.log("arguments is array: " + (arguments instanceof Array)); //false 83 console.log("arguments.length: " + arguments.length); 84 if(arguments.length > 0) 85 console.log("arguments[0]: " + arguments[0]); 86 console.log("arguments.callee: " + arguments.callee); 87 console.log("arguments.callee.caller: " + arguments.callee.caller); 88 console.log("\n"); 89 } 90 91 function fun2(){ 92 console.log("run " + arguments.callee); 93 console.log("arguments is array: " + (arguments instanceof Array)); //false 94 console.log("arguments.length: " + arguments.length); 95 console.log("arguments.callee: " + arguments.callee); 96 console.log("arguments.callee.caller: " + arguments.callee.caller); 97 console.log("\n") 98 99 fun1(1); 100 } 101 102 fun1(); 103 fun2(); 104 105 console.log("host"); 106 if(arguments){ 107 console.log("host arguments.length: " + arguments.length); 108 console.log("host arguments.callee: " + arguments.callee); 109 console.log("host arguments.callee.caller: " + arguments.caller); //undefined 110 } 111 } 112 113 114 run function fun1(){ //运行fun2中的fun1() 115 console.log("run " + arguments.callee); 116 console.log("arguments is array: " + (arguments instanceof Array)); //false 117 console.log("arguments.length: " + arguments.length); 118 if(arguments.length > 0) 119 console.log("arguments[0]: " + arguments[0]); 120 console.log("arguments.callee: " + arguments.callee); 121 console.log("arguments.callee.caller: " + arguments.callee.caller); 122 console.log("\n"); 123 } 124 arguments is array: false 125 arguments.length: 1 126 arguments[0]: 1 127 arguments.callee: function fun1(){ 128 console.log("run " + arguments.callee); 129 console.log("arguments is array: " + (arguments instanceof Array)); //false 130 console.log("arguments.length: " + arguments.length); 131 if(arguments.length > 0) 132 console.log("arguments[0]: " + arguments[0]); 133 console.log("arguments.callee: " + arguments.callee); 134 console.log("arguments.callee.caller: " + arguments.callee.caller); 135 console.log("\n"); 136 } 137 arguments.callee.caller: function fun2(){ 138 console.log("run " + arguments.callee); 139 console.log("arguments is array: " + (arguments instanceof Array)); //false 140 console.log("arguments.length: " + arguments.length); 141 console.log("arguments.callee: " + arguments.callee); 142 console.log("arguments.callee.caller: " + arguments.callee.caller); 143 console.log("\n") 144 145 fun1(1); 146 } 147 148 149 host //最后运行宿主函数,使它执行了这个脚本 150 host arguments.length: 5 151 host arguments.callee: function (exports, require, module, __filename, __dirname) { function fun1(){ 152 console.log("run " + arguments.callee); 153 console.log("arguments is array: " + (arguments instanceof Array)); //false 154 console.log("arguments.length: " + arguments.length); 155 if(arguments.length > 0) 156 console.log("arguments[0]: " + arguments[0]); 157 console.log("arguments.callee: " + arguments.callee); 158 console.log("arguments.callee.caller: " + arguments.callee.caller); 159 console.log("\n"); 160 } 161 162 function fun2(){ 163 console.log("run " + arguments.callee); 164 console.log("arguments is array: " + (arguments instanceof Array)); //false 165 console.log("arguments.length: " + arguments.length); 166 console.log("arguments.callee: " + arguments.callee); 167 console.log("arguments.callee.caller: " + arguments.callee.caller); 168 console.log("\n") 169 170 fun1(1); 171 } 172 173 fun1(); 174 fun2(); 175 176 console.log("host"); 177 if(arguments){ 178 console.log("host arguments.length: " + arguments.length); 179 console.log("host arguments.callee: " + arguments.callee); 180 console.log("host arguments.callee.caller: " + arguments.caller); //undefined 181 } 182 } 183 host arguments.callee.caller: undefined
*结果分析
---如何理解函数的属性(个人目前的想法)
每一个函数(这里指函数的源码脚本), 都对应一个执行上下文(这是运行时维护的对函数的一种描述), 函数的参数也在这个执行上下文中定义;
函数的每次被执行时, 解释器都将同步的去修改这个函数对应的上下文中的相关定义, 包括像arguments等属性的定义.
---脚本函数(宿主函数, 或许这些称呼都不正确)
像示例中的fun1()执行时, 可以发现它也有一个caller; 在示例的最后直接调用arguments(看看最后的host部分), 可以发现整个脚本t_func也同样被定义成了一个函数,
只是arguments.caller的值是undefined.
可以说, 每个js脚本也在运行环境里被定义为一个执行上下文.
---疑问, 为啥测试arguments的类型时, 它不是Array类型呢?
事实就是如此, 它不是一个Array类型但是可以用'[]'来运算. 不知为何要设计成这样.
*参考