" bar"的目的是什么? in" var foo = function bar(){...}"?

时间:2015-07-22 19:24:33

标签: javascript

在Douglas Crockford的书中,他写了一个递归函数:

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(){...}的函数 - 我一直认为声明的右边是匿名者:var foo = function (){...}

声明右侧名称walk的唯一目的是缩短walk_the_DOM的号码吗?它们似乎成为相同功能的独立名称。也许我误解了这个片段是如何工作的。

在变量声明和函数构造中是否存在命名函数的功能原因?

2 个答案:

答案 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 )。

如果这令人困惑,这里有一个更为简洁的行为描述可能会有所帮助:声明被提升,而非分配。只要你理解了函数声明和函数表达式之间的区别,那就是你需要知道的全部内容。 :)

答案 1 :(得分:2)

通过编写var foo = function (){...},您声明了一个名为foo的变量,它包含一个匿名函数。通过编写var foo = function bar(){...},您将声明一个名为foo的变量,该变量将命名函数保存为bar。正如@ jmar777在他的回答中指出的那样,在调试和修复错误时跟踪堆栈跟踪很有用。