谁调我:arguments.callee.caller

发布于 2022-09-30 19:46:56 字数 2127 浏览 15 评论 0

转:Snandy

谁调我:arguments.callee.caller

某知名互联网公司的一道JS笔试题:有函数a,b,c,c可能是在a或b内调用的,怎么知道?

马上就想到了arguments.callee.caller,实际上有许多值得商榷的地方。如

  1. 1 function a(){  
  2. 2     c();        //()调用  
  3. 3     //c.apply(null);//apply调用  
  4. 4     //c.call(null); //call调用  
  5. 5 }  
  6. 6 function c(){alert(arguments.callee.caller);}

复制代码分别用不同函数调用方式测试a

  1. 1 a();  
  2. 2 a.apply(null);  
  3. 3 a.call(null);

复制代码可以看到分别以上三种方式调用,c内部通过arguments.callee.caller知道自己是被谁调用的。这在所有浏览器下都是一致的。

但如果c在a内是用eval执行的呢?

  1. 1 function a(){  
  2. 2     //c();  
  3. 3     //c.apply();  
  4. 4     //c.call();  
  5. 5     eval('c()');  
  6. 6 }  
  7. 7 function c(){alert(arguments.callee.caller);}  
  8. 8 a();

复制代码eval中的代码会运行在当前闭包中,即a内,所有浏览器都一致。但这次只有 IE9/Firefox/Safari/Chrome/Opera 弹出了function a,即仍然知道自己被谁调用的,IE6/7/8 中显示的是null,没有弹出是被谁调用的。

IE9/Firefox/Chrome/Opera

eval中代码能保证运行在当前闭包中(函数a内),c内部通过arguments.callee.caller也能访问被调用函数。
IE6/7/8/Safari

eval中代码能保证运行在当前闭包中(函数a内),但c内部通过arguments.callee.caller则不能访问被调用函数。

该题的答案应该是:
1,当c在a内通过小括号(),apply,call调用时,c内可通过arguments.callee.caller访问到调用函数a
2,当c在a内通过eval方式执行时,IE9/Firefox/Chrome/Opera中可通过arguments.callee.caller访问到调用函数a,IE6/7/8/Safari则不可以。

各浏览器实现差异,是否知道"我被谁调用的?"与调用方式有关。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文