谁调我:arguments.callee.caller
转:Snandy
谁调我:arguments.callee.caller
某知名互联网公司的一道JS笔试题:有函数a,b,c,c可能是在a或b内调用的,怎么知道?
马上就想到了arguments.callee.caller,实际上有许多值得商榷的地方。如
- 1 function a(){
- 2 c(); //()调用
- 3 //c.apply(null);//apply调用
- 4 //c.call(null); //call调用
- 5 }
- 6 function c(){alert(arguments.callee.caller);}
复制代码分别用不同函数调用方式测试a
- 1 a();
- 2 a.apply(null);
- 3 a.call(null);
复制代码可以看到分别以上三种方式调用,c内部通过arguments.callee.caller知道自己是被谁调用的。这在所有浏览器下都是一致的。
但如果c在a内是用eval执行的呢?
- 1 function a(){
- 2 //c();
- 3 //c.apply();
- 4 //c.call();
- 5 eval('c()');
- 6 }
- 7 function c(){alert(arguments.callee.caller);}
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论