论坛首页 Web前端技术论坛

谁调我:arguments.callee.caller

浏览 1695 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2010-06-07   最后修改:2010-06-07

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


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

 

function a(){
	c();		//()调用
	//c.apply(null);//apply调用
	//c.call(null); //call调用
}
function c(){alert(arguments.callee.caller);}

 

分别用不同函数调用方式测试a(见:具名函数的调用方式 ):

 

a();
a.apply(null);
a.call(null);

 

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

但如果c在a内是用eval执行的呢,如下:

 

function a(){
	//c();
	//c.apply();
	//c.call();
	eval('c()');
}
function c(){alert(arguments.callee.caller);}
 

eval中的代码会运行在当前闭包中,即a内。所有浏览器都一致,见:window.eval与eval的区别
但这次只有 Firefox/Safari/Chrome 弹出了function a,即仍然知道自己被谁调用的,Opera/IE 中显示的是null,没有弹出是被谁调用的。

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

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

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

 

   发表时间:2010-06-08  
eval的window.eval不同浏览器的结果不一致的问题只要知道什么情况会有什么样的结果即可。个人愚见- -|
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics