某知名互联网公司的一道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则不可以。
各浏览器实现差异,是否知道"我被谁调用的?"与调用方式有关。
分享到:
相关推荐
JavaScript中的`arguments.callee`是一个在函数内部引用当前正在执行的函数对象的属性。这个属性在函数递归、保持函数封装性以及匿名函数自我引用等场景中尤其有用。然而,由于`arguments`对象是一个相对昂贵的操作...
这个特性在早期版本的JavaScript(ES5之前)中被广泛使用,但在ES6及以后的版本中,由于对`arguments`对象进行了优化,并引入了剩余参数和默认参数等新特性,`arguments.callee`逐渐被淘汰。 `arguments.callee`的...
JavaScript中的隐含参数`arguments`, `callee`, 和 `caller`是函数内部的特殊变量,它们提供了关于函数调用的重要信息。下面将详细解释这三个参数的使用方法。 **arguments对象** `arguments`对象是一个非常有用的...
在JavaScript编程中,arguments、caller和callee是函数对象自带的三个隐含参数,它们为开发者提供了额外的函数执行信息,尤其在处理函数参数、递归调用以及调用栈追踪时非常有用。下面详细介绍这些隐含参数的使用...
var a = callerDemo.caller.toString(); alert(a); } else { alert("this is a top function"); } } function handleCaller() { callerDemo(); } ``` 在上面的例子中,handleCaller调用callerDemo,...
JavaScript中的arguments、caller和callee是与函数调用相关的几个重要概念,它们分别代表函数调用时传递的参数对象、调用当前函数的函数以及当前正在执行的函数。 首先,我们来了解arguments。在JavaScript中,当...
alert(caller.caller.toString()); } else { alert("函数直接执行"); } } ``` 在这个例子中,如果`caller`函数被另一个函数调用,它将显示调用者的代码。如果直接执行,比如在控制台直接调用`caller()`,则会弹...
关于arguments,callee,caller等的测试 function testArg() { var sTemp =”test()开始执行\n\n函数定义的正文:\n\n”; sTemp+=arguments.callee + “\n\n”; sTemp+=”传入参数的长度:\n”; sTemp+=arguments....
### 理解JavaScript中的`caller`...综上所述,理解`caller`、`callee`、`call`、`apply`以及`arguments`对象在JavaScript编程中至关重要,它们不仅增强了函数的灵活性和复用性,还提供了深入分析和调试代码的强大工具。
本文实例讲述了JavaScript中callee和caller的区别与用法。分享给大家供大家参考,具体如下: 1.callee 在函数的内部,有两个特殊的对象:arguments和this。其中arguments是一个类似数组的对象,包含着传入函数的所有...
var a = arguments.caller.toString(); alert(a); } else { alert("this is a top function"); } } handleCaller(); ``` 在这个例子中,`callerDemo` 函数被`handleCaller`函数调用,`callerDemo`通过`...
这篇文章将深入探讨四个关键概念:caller、callee、call和apply,它们都是JavaScript函数操作的核心部分,对于理解和使用高级JavaScript编程至关重要。 首先,我们来了解`caller`和`callee`。在JavaScript的函数...
可以考虑使用`arguments.callee.caller.arguments[0]`来代替,这是因为`arguments.callee.caller`可以指向调用当前函数的上一个函数,而`caller.arguments[0]`则通常为事件对象。 ```javascript function ...
6. **`arguments.callee`和`arguments.caller`**: 在ES5及之前,`arguments.callee`引用当前执行的函数,`arguments.caller`则返回调用当前函数的函数。然而,由于这些属性可能导致性能问题和难以调试的代码,它们...
虽然在严格模式下,使用caller属性可能会导致错误,但在某些情况下,它可以帮助我们跟踪函数调用链,尤其是在处理嵌套函数或回调函数时。 Arguments对象在JavaScript中扮演的角色之一是模拟方法重载。由于...
因此,在`myFunc()`内部,`arguments.callee.caller`指向`onclick`函数,而`arguments.callee.caller.arguments[0]`就是`event`对象。 总结一下,获取`event`对象的方法在不同的浏览器环境中有所不同: - Internet...