在下面的第一个片段中,基于我的理解,我正在创建一个函数并将其分配给变量。但这是否意味着该函数将采用该变量的名称?
var aFunc = function(){};
我知道这是命名函数。
function bFunc(){};
答案 0 :(得分:3)
没有
在第一个示例中,您将创建一个匿名函数,然后将其分配给“aFunc”
在第二个例子中,你声明一个函数并将其命名为bFunc。
两者之间最显着的区别是你不能在分配它之前调用“aFunc”。
答案 1 :(得分:3)
不,该功能不会“取变量的名称”。该变量将保存对匿名函数的引用。该功能本身仍然是匿名的。
请注意,这在最后几乎没有什么区别,但是这个函数引用一旦被赋值,就可以被视为与任何常规命名函数完全相同。实际上,它的差别很小,命名函数也可以像持有函数引用的变量一样对待:
function foo() { }
foo();
foo = 'bar';
alert(foo); // bar
答案 2 :(得分:3)
术语“匿名函数”是行话,所以它的意思很可能会随着时间而改变。没有规范说明它是什么,所以它可以是你想要的任何东西。无论你决定什么,都可能会受到其他人的质疑。术语就像那样(查看“trunking”这个词,这是电话中常用的术语)。
严格来说,有一些函数声明,其中名称是必需的,例如
function foo() {
...
}
和函数表达式,其中名称是可选的。如果名称丢失,例如:
var x = function () {
...
};
那么,对我来说,这是一个匿名函数。如果它有一个名字,例如
var x = function foo() {
...
};
然后它是一个命名函数表达式(而不是匿名函数)。从我的角度来看,任何没有可选名称的函数表达式都是匿名函数。函数表达式有很多用途,例如
// assignment to a variable
var x = function() {...}
// pass as a parameter
foo(function(){...})
// immediately executed and pass the result
foo( (function(){...}()) )
等等。所以在OP中,赋值的右边是一个没有名字的函数表达式,所以对我来说,这是一个匿名函数。然后将其分配给标识符的事实不会突然使其成为命名函数表达式。
其他人可能会有所不同。
顺便提一下,结果:
function foo(){}
和
var foo = function(){};
几乎无法区分,主要区别在于创建函数时。
答案 3 :(得分:3)
因此,首先我们要澄清你所写的两个函数之间的主要区别。
这一个:
var aFunc = function(){};
是函数表达式。这一个:
function bFunc(){};
是函数声明。
在函数表达式中,您使用function operator来定义表达式中的函数。 当您声明一个函数时,您正在使用function statement。
一开始它可能会让人感到困惑,因为它们非常相似,但函数声明和函数表达式表现不同。首先,您不能声明一个匿名函数:如果您使用的是函数语句,则该名称是必需的。 因此,只有使用函数运算符定义的函数才能是匿名的:
var aFunc = function(){};
这是一个匿名函数。在某些浏览器中,您实际上可以打印function's name并自己查看:
console.log(aFunc.name);
(请注意,这还不是标准,但有一个proposal)
但这并不意味着用函数运算符声明的函数必须是匿名的。例如:
var aFunc = function myFunction() {};
这是一个命名函数。但是,这仍然与具有这样的函数声明不同:
function myFunction() {};
var aFunc = myFunction;
为什么呢?因为在函数表达式的情况下,您不在范围中声明myFunction
函数:
var aFunc = function myFunction() {};
console.log(typeof myFunction) // undefined, unless some bugs
那么为函数表达式命名是什么意思?答案是:从函数体本身访问该函数,而不会污染范围。例如,您想要将事件侦听器添加到DOM节点,但只执行一次侦听器:
document.body.addEventListener("click", function onclick() {
// do something
document.body.removeEventListener("click", onclick, false);
}, false);
因此,您不会使用许多仅用于此类目的的函数来污染范围,并且您仍然可以从函数体中访问该函数。这在ES5中特别有用,其中arguments.callee
已被弃用,以及递归。
函数表达式之间的另一个区别是您可以立即调用它们,但是您不能为函数声明执行此操作。所以,例如:
function() {
console.log('foo');
}();
将抛出异常,因为引擎无法理解它是函数声明还是函数表达式。但是如果你强迫引擎把它看作一个表达式:
!function() {
console.log('foo');
}();
// or
(function(){
console.log('foo');
}());
// etc, there are a lot of ways
我们在这里:JS理解是一个表达式,因此威胁function
作为运算符而不是语句。并且您获得了IIFE(立即调用的函数表达式),它在许多场景中都很有用,特别是在您想要隔离代码的地方。
那么,回到你的问题,为什么这个函数的名称:
var aFunc = function(){};
不是aFunc
?
因为,这是一个表达。所以该值对左侧的赋值一无所知。这就像是:
var aFunc = -3;
-
是Unary Negation operation而3
是值:他们对aFunc
一无所知,对吧?它与函数表达式完全相同,其中function
是运算符,(){}
是值。
答案 4 :(得分:2)