命名功能
函数可以是命名的或未命名的( 匿名函数 ):
var namedSum = function sum (a, b) { // named
return a + b;
}
var anonSum = function (a, b) { // anonymous
return a + b;
}
namedSum(1, 3);
anonSum(1, 3);
4
4
但是他们的名字属于他们自己的范围:
var sumTwoNumbers = function sum (a, b) {
return a + b;
}
sum(1, 3);
未捕获的 ReferenceError:未定义 sum
命名函数与多个场景中的匿名函数不同:
- 在调试时,函数的名称将出现在错误/堆栈跟踪中
- 命名函数被挂起而匿名函数则不被挂起
- 处理递归时,命名函数和匿名函数的行为会有所不同
- 根据 ECMAScript 版本,命名和匿名函数可能会以不同方式处理函数
name
属性
命名函数被悬挂
使用匿名函数时,只能在声明行之后调用该函数,而在声明之前可以调用命名函数。考虑
foo();
var foo = function () { // using an anonymous function
console.log('bar');
}
未捕获的 TypeError:foo 不是函数
foo();
function foo () { // using a named function
console.log('bar');
}
bar
递归方案中的命名函数
递归函数可以定义为:
var say = function (times) {
if (times > 0) {
console.log('Hello!');
say(times - 1);
}
}
//you could call 'say' directly,
//but this way just illustrates the example
var sayHelloTimes = say;
sayHelloTimes(2);
你好!
你好!
如果你的代码中某处原始函数绑定被重新定义怎么办?
var say = function (times) {
if (times > 0) {
console.log('Hello!');
say(times - 1);
}
}
var sayHelloTimes = say;
say = "oops";
sayHelloTimes(2);
你好!
未捕获的 TypeError:说不是函数
这可以使用命名函数来解决
// The outer variable can even have the same name as the function
// as they are contained in different scopes
var say = function say (times) {
if (times > 0) {
console.log('Hello!');
// this time, 'say' doesn't use the outer variable
// it uses the named function
say(times - 1);
}
}
var sayHelloTimes = say;
say = "oops";
sayHelloTimes(2);
你好!
你好!
作为奖励,命名函数不能设置为 undefined
,即使是从内部:
var say = function say (times) {
// this does nothing
say = undefined;
if (times > 0) {
console.log('Hello!');
// this time, 'say' doesn't use the outer variable
// it's using the named function
say(times - 1);
}
}
var sayHelloTimes = say;
say = "oops";
sayHelloTimes(2);
你好!
你好!
函数的 name
属性
在 ES6 之前,命名函数将 name
属性设置为其函数名称,匿名函数将其 name
属性设置为空字符串。
Version <= 五
var foo = function () {}
console.log(foo.name); // outputs ''
function foo () {}
console.log(foo.name); // outputs 'foo'
在 ES6 之后,命名和未命名的函数都设置了他们的 name
属性:
Version >= 6
var foo = function () {}
console.log(foo.name); // outputs 'foo'
function foo () {}
console.log(foo.name); // outputs 'foo'
var foo = function bar () {}
console.log(foo.name); // outputs 'bar'