4

我知道如何解决这个错误,但有人告诉我为什么会发生这个错误的全面解释吗?

var fn = function () {
  return fn();
}(); //uncaught TypeError: Property 'fn' of object [object DOMWindow] is not a function
4

4 回答 4

3

当您在全局范围内使用 var 关键字时,声明的变量将成为全局对象的属性。在 Web 浏览器中,全局对象是window对象,它本身是DOMWindow(). 因此,利用这些知识,我们可以将您的代码重写为如下所示:

window.fn = function () {
    return window.fn();
}();

去掉最初的分配,我们有

(function () {
    return window.fn();
})();

...它定义了一个匿名函数,其中window.fn()被调用。然而,在这段代码运行的时候,window.fn它不是一个函数(永远不会是),所以会抛出一个异常,因为你试图调用它,即使它没有内部[[Call]]标志。

如果您取消匿名函数的立即执行,那么window.fn将是一个函数:

var fn = function () {
    return fn();
}
fn(); //-> infinite loop
于 2011-09-11T12:09:38.793 回答
2
var fn = function () {
  return fn();
}();
  1. 上面的代码是一个变量语句。该变量fn被声明为我设置的值undefined(现在)。

  2. function () {}()是一个IIFE。IIFE 是一个立即调用的函数。

  3. IIFE 包含一个声明——一个return声明。由于 IIFE 已被调用,该return语句将立即执行。

  4. return语句包含以下表达式:fn()- 这是一个函数调用。但fn此时此刻是什么?它是一个函数吗?不,它仍然是undefined。调用该undefined值将引发错误。


我假设您可能想要实现这种模式:

var fn = (function () {

    var private = 0;

    function utility() { ... }

    return function () { ... };

})();

现在,是一个对变量和私有函数fn具有独占访问权的函数。privateutility

于 2011-09-11T12:11:03.813 回答
1

你说的是

  1. 执行函数function () { return fn(); }
  2. 将返回值存储在一个名为fn

当然,问题是当 #1 发生时,fn还没有定义,所以函数调用不能使用它;fn不是功能。这和说“将X的值设置为X的值”是一样的,没有意义。

除了您实际上是在尝试返回call的结果fn,这更没有意义。因此,即使它以某种方式没有抱怨fn尚未定义,您仍然会得到一个无限递归,其中函数调用返回返回值的返回值的返回值......<br> 正如 Shef 所说,这就是所谓的堆栈溢出错误

于 2011-09-11T11:57:48.867 回答
-2
var fn = function () {
  return this;
}();

你不能这样写,因为变量类型函数定义没有在其他代码之前详细说明。除了你试图做的事情没有任何意义。您可以创建如下函数:

function fn(){
    return fn();
}

fn();

但是你会遇到stack_overflow错误。

于 2011-09-11T10:41:49.123 回答