开发者

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

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

v开发者_开发百科ar 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜