Почему имя функции исчезает при назначении переменной var? - программирование

Почему имя функции исчезает при назначении переменной var?

Я пытаюсь получить более глубокое понимание того, как работает Javascript, и следующий код прослушивает меня:

function notInVar(a, b) {
    return a + b
}

var inVar = function doesThisWork(a, b) {
    return a + b
}

document.writeln('2 + 2 = ' + notInVar(2, 2));
document.writeln('3 + 3 = ' + inVar(3, 3));
document.writeln('4 + 4 = ' + doesThisWork(4, 4));

В Chrome первые два файла document.writelns выполняются так, как ожидалось, затем я получаю "Uncaught ReferenceError: doesThisWork is not defined" в Chrome. Почему я не могу вызвать вторую функцию по имени doesThisWork? В этом случае, где хранится первый объект-объект notInVar?

4b9b3361

Ответ 1

Функции - это объекты. Переменная inVar содержит объект функции с именем doesThisWork.

inVar.name //=> "doesThisWork"

Если функция не имеет имени, она анонимна.

Чтобы вызвать функцию, хранящуюся в переменной, вы используете имя переменной (ссылка на этот объект). Если вы хотите вызвать функцию внутри той же функции (для рекурсии), вы можете вызвать ее по ее имени, в этом случае doesThisWork.

Ответ 2

Второе определение называется названное выражение функции и из-за характера этого определения, единственный способ, которым вы можете назвать его по имени, - это изнутри тела функции:

var inVar = function doesThisWork(a, b) {
    return doesThisWork(a + b); // infinite recursion!
}

Это может быть использовано для достижения рекурсии внутри анонимной функции, без необходимости использовать что-то вроде Y-combinator.

Ответ 3

В этом случае, где хранится первый объект-объект notInVar?

function notInVar(a, b) {
    return a + b
}

Является эквивалентным

var notInVar = function (a, b) {
        return a + b
}

В вашем случае notInVar хранится в глобальной области.

тогда я получаю сообщение "Uncaught ReferenceError: doesThisWork не определено" в Chrome

var inVar = function doesThisWork(a, b) {
    return a + b
}

похож на

var inVar = function (a, b) {
        return a + b
    }

когда он обратился к вне функции

Вы не можете получить доступ к функции с помощью doesThisWork, но вам нужно получить к ней доступ inVar

Ответ 4

Как вы его написали, doesThisWork доступен только внутри себя.

Ответ 5

Функция - это переменная, и область действия переменной имеет значение. Для второй функции в глобальной области ее имя переменной InVar. Имя функции doesThisWork находится внутри собственной области видимости и не отображается в глобальной области. Поэтому вы можете использовать inVar, а не doesThisWork.

Ответ 6

Ну, есть несколько вещей об этом:

сначала: имя функции будет локальным, поэтому вы можете вызывать одну и ту же функцию только внутри локально. который может вызвать бесконечную рекурсию при ее использовании, если она не будет отфильтрована как if(doesThisWork.caller != doesThisWork) return doesThisWork(a,b);.

Вторым является то, что вы назначаете имя функции (не оставляя ее как анонимную функцию), а локально к ней.

TL; DR = > перейти к анализу для более четкой идеи.

Интересно отметить различия между методами объявления функций:

встроенное объявление:

var x = function fnName(){}; console.log(x.prototype); => fnName {} // but used locally to x
var x = function(){}; console.log(x.prototype); => Object {} // no local name, only global x

во время разбора/времени выполнения:

function fnName(){}; console.log(fnName.prototype); => fnName {} // global* and local name

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

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