Uncaught TypeError: Property 'fn' of object [object DOMWindow] is not a function

StackOverflow https://stackoverflow.com/questions/7377653

  •  28-10-2019
  •  | 
  •  

I know how to fix this error but does anyone tell me a comprehensive explanation of why this error occurs?

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

解决方案

When you use the var keyword in the global scope, the declared variable becomes a property of the global object. In a web browser, the global object is the window object, which itself is an instance of DOMWindow(). So, using that knowledge we can rewrite your code to look like this:

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

Taking away the initial assignment, we have

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

...which defines an anonymous function wherein window.fn() is called. However, at the point this code runs, window.fn is not a function (and never will be), so an exception is thrown because you're trying to invoke it even though it doesn't have an internal [[Call]] flag.

If you take away the immediate execution of the anonymous function, then window.fn would be a function:

var fn = function () {
    return fn();
}
fn(); //-> infinite loop

其他提示

var fn = function () {
  return fn();
}();
  1. The above code is a variable statement. The variable fn is declared an it's value i set to undefined (for now).

  2. function () {}() is an IIFE. An IIFE is a function which is invoked immediately.

  3. That IIFE contains one statement - a return statement. Since the IIFE has been invoked, that return statement is executed immediately.

  4. That return statement contains this expression: fn() - it's a function invocation. But what is fn at this moment? Is it a function? No. It's still undefined. Invoking the undefined value will throw an error.


I assume you probably want to achieve the this pattern:

var fn = (function () {

    var private = 0;

    function utility() { ... }

    return function () { ... };

})();

Now, fn is a function which has exclusive access to the private variable and the utility private function.

What you're saying is

  1. Execute the function function () { return fn(); }
  2. Store the returned value in a variable called fn

Trouble is, of course, that when #1 is happening, fn hasn't been defined yet, so the function call can't use it; fn is not function. It's the same as saying "set the value of X to the value of X", which doesn't make sense.

Except you're actually trying to return the result of calling fn, which makes even less sense. So even if it somehow didn't complain about fn not being defined yet, you'd still get an infinite recursion where the function call returns the returned value of the returned value of the returned value …
As Shef says, that's what's called a stack overflow error

var fn = function () {
  return this;
}();

You can't write that, because variable type function definition is not elaborated before the other code. Besides what you are trying to do makes no sense. You could create the function like:

function fn(){
    return fn();
}

fn();

But you are going to hit a stack_overflow error.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top