揭秘命名函数表达式
使用: 在Debug或者Profiler分析的时候来描述函数的名称
使用函数名实现递归
声明和表达式: 声明必须有函数名,表达式可有可无
函数声明: function 函数名称 (参数:可选){ 函数体 }
函数表达式: function 函数名称(可选)(参数:可选){ 函数体 }
区分: function foo(){}是作为赋值表达式的一部分的话,那它就是一个函数表达式
()是一个分组操作符,它的内部只能包含表达式
(function foo(){}),他是表达式的原因是因为括号 ()是一个分组操作符
eval('(' + json + ')'),这样做的原因就是因为分组操作符,
这对括号,会让解析器强制将JSON的花括号解析成表达式而不是代码块
在条件语句内,尽量使用表达式
// 相反,这样情况,我们要用函数表达式
var foo;
if (true) {
foo = function() {
return 'first';
};
}
else {
foo = function() {
return 'second';
};
}
foo();
命名函数表达式:
函数表达式在实际应用中还是很常见的,在web开发中友个常用的模式是基于对某种特性的测试来伪装函数定义,
从而达到性能优化的目的
---------
// 该代码来自Garrett Smith的APE Javascript library库(http://dhtmlkitchen.com/ape/)
var contains = (function() {
var docEl = document.documentElement;
if (typeof docEl.compareDocumentPosition != 'undefined') {
return function(el, b) {
return (el.compareDocumentPosition(b) & 16) !== 0;
};
}
else if (typeof docEl.contains != 'undefined') {
return function(el, b) {
return el !== b && el.contains(b);
};
}
return function(el, b) {
if (el === b) return false;
while (el != b && (b = b.parentNode) != null);
return el === b;
};
})();
---------
var bar = function foo(){};就是一个有效的命名函数表达式,但有一点需要记住:这个名字只在新定义的函数作用域内有效
typeof foo; // "undefined"
查看调用栈的信息可以查看函数的 ·> 调用顺序 和 命名的函数
归根结底,只有给函数表达式取个名字,才是最委托的办法,也就是使用命名函数表达式。
// 此前,你可能会使用arguments.callee
(function(x) {
if (x <= 1) return 1;
return x * arguments.callee(x - 1);
})(10);
// 但在严格模式下,有可能就要使用命名函数表达式
(function factorial(x) {
if (x <= 1) return 1;
return x * factorial(x - 1);
})(10);
// 要么就退一步,使用没有那么灵活的函数声明
function factorial(x) {
if (x <= 1) return 1;
return x * factorial(x - 1);
}
factorial(10);