js函数的两个概念:函数声明、函数表达式
函函数声明:function fnName () {…};使用function关键字声明一个函数,再指定一个函数名,叫函数声明。
函数表达式 var fnName = function () {…};使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予一个变量,叫函数表达式,这是最常见的函数表达式语法形式。匿名函数也属于函数声明。
函数声明和函数表达式不同之处在于:
一、Javascript引擎在解析javascript代码时会有‘函数声明提升’(Function declaration Hoisting),函数表达式不会。
二、函数表达式后面可以加括号立即调用该函数,函数声明不可以,只能以fnName()形式调用 。所以,要在函数体后面加括号就能立即调用,则这个函数必须是函数表达式,不能是函数声明(因此也不能使匿名函数形式)。
(function(a){
console.log(a); //firebug输出123,使用()运算符
})(123);
(function(a){
console.log(a); //firebug输出1234,使用()运算符
}(1234));
!function(a){
console.log(a); //firebug输出12345,使用!运算符
}(12345);
+function(a){
console.log(a); //firebug输出123456,使用+运算符
}(123456);
-function(a){
console.log(a); //firebug输出1234567,使用-运算符
}(1234567);
var fn=function(a){
console.log(a); //firebug输出12345678,使用=运算符
}(12345678)
()、!、+、-、=等运算符,都可以将函数声明转换成函数表达式,消除javascript引擎识别函数表达式和函数声明的歧义,告诉javascript引擎这是一个函数表达式,不是函数声明,可以在后面加括号,并立即执行函数的代码。 加括号是最安全的做法,因为!、+、-等运算符还会和函数的返回值进行运算,有时造成不必要的麻烦。
这样写的用处在于:由于javascript中没用私有作用域的概念,但可以通过函数作用域链的特性模仿一个私有作用域,在该作用域内可以访问外部的变量,但不能从外部访问这个作用域内部的变量,从而避免对全局变量的污染。俗称“匿名包裹器”或“命名空间”