先了解一下创建函数的方式
//函数声明
function functionName(){
//执行代码
}
//函数表达式
var functionName = function(){
//执行代码
}
// 匿名函数
function(){
//执行代码
}
自执行函数严格来说也是函数表达式中的一种,立即执行函数的格式如下:
(function(i){
......
}(123)) //传参
(function(i){
.....
})(123)
(function(test){
console.log("第一个:"+test); //输出test的值123
}(123))
(function(test){
console.log("第二个:"+test); //输出test的值123456
})(123456)
-function(test){
console.log("第三个:"+test); //输出123456
}(123456)
+function(test){
console.log("第四个:"+test); //输出test的值123456
}(123456)
!function(test){
console.log("第五个:"+test); //输出test的值123456
}(123456)
~function(test){
console.log("第六个:"+test); //输出test的值123456
}(123456)
var fn = function(test){
console.log("第七个:"+test); //输出test的值123456
}(123456)
使用运算符 ( ) 等等 将其转换为函数表达式之后就可达到立即执行的效果
使用立即执行函数的好处
通过定义一个匿名函数,创建了一个新的函数作用域,相当于创建了一个“私有”的命名空间。该命名空间的变量和方法,不会破坏污染全局的命名空间。在书上看的叫做模仿块级作用域还可以减少闭包占用内存的问题,因为没有指向匿名函数的引用。只要函数执行完毕,就可以立即销毁其作用域链了。
简单说一下块级作用域吧
js里面没有块级作用域的概念,在for循环中的 i ,在函数内部到处可以访问到。而java,c++等for循环执行完,i 就会被销毁。
<h1 onclick="test(3)">点击这里</h1>
function test(count){
for (var i=0;i<count;i++) {
console.log("for循环内:"+i);
}
console.log("for循环外:"+i);
}
输出结果:(i 没有被销毁)
for循环内:0
for循环内:1
for循环内:2
for循环外:3
函数表达式的后面可以跟圆括号。要将函数声明转换成函数表达式,只要像下面这样给它加上一对圆括号即可。
function test(count){
(function (){
for (var i=0;i<count;i++) {
console.log("for循环内:"+i);
}
})();
console.log("for循环外:"+i);
}
输出结果: 外面的 i 报错了
for循环内:0
for循环内:1
for循环内:2
Uncaught ReferenceError: i is not defined