请看以下两个函数:
function a(){ alert("a") }
var b = function(){ alert("b") }
它们俩有何不同呢?翻开书,作者会告诉我们,前者为函数声明,后者为函数表达式。函数声明作为一种声明,当然会在预编译阶级有所动作(声明提前),而函数表达式则不会。另一个区别是,函数声明不能直接加一对括号让它们执行。第三个区别,表达式还可以继续细分,表达式是由常量,变量,操作符,函数等组合而成,计算以后返回一个结果值,至少也会返回一个undefined。
function a (){ alert("a") }();//报错
var b = function(){ alert("b") }();
(function foo(){}); // 表达式:注意它被包含在分组操作符中 var bar = function foo(){}; // 表达式,因为它是赋值表达式的一部分 new function bar(){}; // 表达式,因为它是New表达式的一部分
给 function 外套一对括号(分组操作符)就不报错了,括号是表达式,是表达式就有返回值,所以可以在后面加一对括号让它们执行,再看
(function a (){ alert("a") })();//没有问题
另外,我们知道,函数名的作用就是用来引用的,现在没用了,我们是不是可以把它去掉呢?
(function (){ alert(arguments.callee) })();//弹出自身
知道这个,我们就可以方便地递归自身了。如弄一个深拷贝函数
var deepExtend = function(destination, source) { for (var property in source) { if (source[property] && source[property].constructor && source[property].constructor === Object) { destination[property] = destination[property] || {}; arguments.callee(destination[property], source[property]); } else { destination[property] = source[property]; } } return destination; };
另外,从另一方便也启法了我们如何兼价地批量生产各种各样的自动执行函数。因为把函数转换为表达式的方法并不一定要靠分组操作符,我们还可以用void操作符,~操作符,!操作符……
void function(){ alert("司徒正美"); }()
0, function(){ alert("司徒正美"); }();
-function(){ alert("司徒正美"); }();
+function(){ alert("司徒正美"); }();
!function(){ alert("司徒正美"); }();
~function(){ alert("司徒正美"); }();
typeof function(){ alert("司徒正美"); }();