Uncaught TypeError: Свойство 'fn' объекта [объект DOMWindow] не является функцией - PullRequest
4 голосов
/ 11 сентября 2011

Я знаю, как исправить эту ошибку, но кто-нибудь подскажет подробное объяснение, почему эта ошибка возникает?

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

Ответы [ 4 ]

3 голосов
/ 11 сентября 2011

Когда вы используете ключевое слово var в глобальной области видимости, объявленная переменная становится свойством глобального объекта. В веб-браузере глобальный объект - это объект 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
2 голосов
/ 11 сентября 2011
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 - это функция, которая имеет эксклюзивный доступ к переменной private и закрытой функции utility.

1 голос
/ 11 сентября 2011

То, что вы говорите, это

  1. Выполнить функцию function () { return fn(); }
  2. Сохранить возвращаемое значение в переменной с именем fn

Проблема, конечно, в том, что когда происходит # 1, fn еще не определен, поэтому вызов функции не может его использовать; fn не работает. Это то же самое, что сказать «установить значение X на значение X», что не имеет смысла.

За исключением того, что вы на самом деле пытаетесь вернуть результат вызова fn, что имеет еще меньше смысла. Таким образом, даже если бы он как-то не жаловался на то, что fn еще не определен, вы все равно получите бесконечную рекурсию, где вызов функции возвращает возвращенное значение возвращаемого значения возвращаемого значения…
Как говорит Шеф, это то, что называется ошибкой переполнения стека

0 голосов
/ 11 сентября 2011
var fn = function () {
  return this;
}();

Вы не можете написать это, потому что определение функции типа переменной не разработано перед другим кодом.Кроме того, что вы пытаетесь сделать, не имеет смысла.Вы можете создать такую ​​функцию, как:

function fn(){
    return fn();
}

fn();

Но вы столкнетесь с ошибкой stack_overflow.

...