Почему переменные функции живут, когда функция переопределена? - PullRequest
0 голосов
/ 17 декабря 2010

В качестве продолжения этого вопроса все еще пытается уловить аномалии функций Javascript, кто-то может объяснить, почему работает следующий код?

Мой текст (шаблоны Javascript) гласит:

Если вы создаете новую функцию и назначить его той же переменной, что уже имеет другую функцию, вы перезаписывая старую функцию с новый.

Что заставило бы меня предположить, что в следующем коде переменные count и name будут перекрыты при создании второго определения функции test.

Где живут переменные count и name?

$(document).ready(function() {

    var test = function() {
        var name = 'The Test Function';
        var count = 1;
        console.log(name + ' has been setup');
        test = function() {
            console.log('Number of times ' + name + ' has been called: ' + count);
            count++;
        };
    }
    test();
    test();
    test();
    test();
    test();
});

Выход:

alt text

Ответы [ 3 ]

7 голосов
/ 17 декабря 2010

Вы заменяете test функцию , но вы заменяете ее функцией, которая «закрывает» (имеет постоянную ссылку) переменные, созданные первым вызовом функции. Вот почему вы видите, что они живут, хотя предыдущий вызов функции вернулся. Подробнее о замыканиях здесь , они очень важная часть языка.

Вот разбивка того, что происходит.

  1. Вы создаете функцию и присваиваете ей test.
  2. Вы звоните test.
  3. Интерпретатор JavaScript устанавливает объект, называемый контекст выполнения , для этого вызова test. контекст выполнения имеет нечто, называемое переменный объект . Этот объект (к которому у вас нет прямого доступа) имеет свойства для всех аргументов и var s для этого вызова test.
  4. Ваш код в test настраивает, в том числе создает новую функцию и присваивает ее переменной test. Новая функция имеет постоянную ссылку на контекст выполнения, в котором она была создана, что означает, что, хотя первый вызов test возвращает, новая функция все еще имеет доступ (через объект переменной) к переменным, созданным для вызова .
  5. Вы снова звоните test (новый).
  6. Доступ к переменным (свойствам объекта переменной), созданным при первом вызове.
0 голосов
/ 17 декабря 2010

Функция не была переопределена.Ссылка на новую функцию была назначена переменной, которая ранее содержала ссылку на старую функцию.

Поскольку новая функция ссылается на переменные, определенные в старой функции, они не удаляются сборщиком мусора.

0 голосов
/ 17 декабря 2010

Определяя вторую функцию test внутри первой (где объявлены переменные name и count), вы создаете замыкание, которое сохраняет ссылку на эти переменные , даже если ссылка на старую функцию test пропала.

Если вы возьмете вторую функцию test из первой, вы получите undefined для name и count.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...