2015-07-22 3 views
5

В книге Дугласа Крокфорд, он пишет рекурсивную функцию:Какова цель «bar» в «var foo = function bar() {...}"?

var walk_the_DOM = function walk(node, func){ 
    func(node); 
    node = node.firstChild; 
    while(node){ 
     walk(node,func); 
     node = node.nextSibling; 
    } 
} 

Я никогда не видел функцию, определенную в var foo = function bar(){...} - Я всегда видел правая часть декларации будет anonymou как: var foo = function(){...}

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

Существует ли функциональная причина для именования функции как в объявлении переменной, так и в конструкторе функции?

+0

Кстати, я недостаточно разбираюсь в терминологии, но, возможно, «конструкцию функций» - это не то, что можно назвать ее, я бы не прочь ее исправить/проинформировать об этой терминологии. –

ответ

4

Есть ли функциональная причина для именования функции как в объявлении переменной, так и в конструкторе функции?

Да. function bar() {} вызывает свойство функции name, которое должно быть установлено на bar, что может быть полезно, например, для отладки в трассировке стека.

Что касается некоторых из путаницы имен вы ссылались на это может помочь:

function bar() {} 

^Это функции объявление а, так как она не существует как часть выражения присваивания.

var foo = function() {}; 

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

var foo = function bar() {}; 

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

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

function bar() {} 

var bar = function() {}; 

Я говорю примерно эквивалент, потому что второе утверждение все еще приводит к анонимным функции, а не с именем функция. Там также тонкая разница в том, как декларации функций поднимаются. Рассмотрим, например, следующее:

function test() { 
    hello(); 

    var hello = function() { console.log('hello'); }; 
} 

test(); 
// > TypeError: hello is not a function 

Обратите внимание, что hello технически определен, где мы пытались вызвать его (исключение составляет лишь то, что это не функция (пока)).Это связано с переменным подъемом. Как и ожидалось, мы еще не присвоили нашей функции переменной hello. Это проще показать, чем объяснять, на самом деле. В основном, из-за подъем, выше test примера эквивалентен:

function test() { 
    var hello; // declared, but not assigned yet 

    hello(); 

    hello = function() { console.log('hello'); }; // now the assignment happens 
} 

Сравните с фактической объявлении функции:

function test() { 
    hello(); 

    function hello() { console.log('hello'); }; 
} 

test(); 
// > "hello" 

Обратите внимание, что даже если декларация ниже командования призывания, он по-прежнему работает, потому что декларации функций поднимаются в целом на вершину их области (в данном случае test).

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

+0

Ничего себе, ваше объяснение сработало чудесами. –

2

При написании var foo = function(){...} вы объявляете переменную с именем foo, которая содержит анонимную функцию. Написав var foo = function bar(){...}, вы объявляете переменную с именем foo, которая имеет именованную функцию как bar. Как отметил @ jmar777 в своем ответе, это полезно для отслеживания следов стека при отладке и исправлении ошибок.

Смежные вопросы