我在JavaScript:The Good Parts
一书中读到了以下类型的函数。事情是这样的。
var Foo = function NameOfFunction() {
};
我根本不明白这个功能。如果有人可以一般性地解释这一点以及如何使用它,那就太好了?
书中的具体代码如下,基本上用于递归
var walk_the_DOM = function walk(node, func) {
func(node);
node = node.firstChild();
while (node) {
walk(node, func);
node = node.nextSibling;
}
};
最佳答案
当您使用名称(即 function
关键字后面的名称)实例化函数时,该名称将作为对自身的引用绑定(bind)到函数内部。 在函数外部,除非函数是在函数声明语句中创建的,否则名称不可见。在您的示例中,情况并非如此,因此局部变量“walk_the_DOM”绑定(bind)到该函数。
这里的关键优点是,即使“walk_the_DOM”以某种方式改变了它的值,这样创建的函数也将继续工作(假设对其引用的副本保存在某处)。为什么?因为名称“walk”是在函数内部绑定(bind)的,并且无论“walk_the_DOM”发生什么情况,它都将保持绑定(bind)状态。
所以这个声明有两个部分:
var walk_the_DOM = function walk(node, func) {
func(node);
node = node.firstChild;
while (node) {
walk(node, func);
node = node.nextSibling;
}
};
第一部分是
var walkt_the_DOM ...
这是一个简单的 var
声明,它创建的变量在任何方面都不是特别特殊。它的值由初始化表达式确定:
... = function walk(node, func) {
func(node);
node = node.firstChild;
while (node) {
walk(node, func);
node = node.nextSibling;
}
};
这恰好是一个函数实例化。
如果函数声明时没有名称,会发生什么情况?像这样:
var walk_the_DOM = function(node, func) {
func(node);
node = node.firstChild;
while (node) {
walk_the_DOM(node, func); // NOTE CHANGE HERE
node = node.nextSibling;
}
};
这会起作用,除非由于某种原因“walk_the_DOM”发生变化:
var thatFunction = walk_the_DOM;
walk_the_DOM = "hello world";
thatFunction(whatever, someFunc); // WILL NOT WORK
我们已经保存了对该函数的引用,但由于此版本中的函数希望能够通过外部(函数的)变量“walk_the_DOM”“找到自身”,所以它失败了,因为“walk_the_DOM”没有更长指的是功能。这就是为函数指定自己的名称的优点。
Here is a classic article on the topic.请注意,该文章指出了一些实现错误,但它有点过时,我认为现代浏览器做得更好。
关于JavaScript 将命名函数分配给变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21352892/