先要理解清楚几个概念:

 

以下转自:http://www.cnblogs.com/TomXu/archive/2011/12/31/2289423.html 

问题的核心

当你声明类似function foo(){}或var foo = function(){}函数的时候,通过在后面加个括弧就可以实现自执行,例如foo(),看代码:

// 因为想下面第一个声明的function可以在后面加一个括弧()就可以自己执行了,比如foo(),
// 因为foo仅仅是function() { /* code */ }这个表达式的一个引用

var foo = function(){ /* code */ }

// ...是不是意味着后面加个括弧都可以自动执行?

function(){ /* code */ }(); // SyntaxError: Unexpected token (
//

上述代码,如果甚至运行,第2个代码会出错,因为在解析器解析全局的function或者function内部function关键字的时候,默认是认为function声明,而不是function表达式,如果你不显示告诉编译器,它默认会声明成一个缺少名字的function,并且抛出一个语法错误信息,因为function声明需要一个名字。

旁白:函数(function),括弧(paren),语法错误(SyntaxError)

有趣的是,即便你为上面那个错误的代码加上一个名字,他也会提示语法错误,只不过和上面的原因不一样。在一个表达式后面加上括号(),该表达式会立即执行,但是在一个语句后面加上括号(),是完全不一样的意思,他的只是分组操作符。

// 下面这个function在语法上是没问题的,但是依然只是一个语句
// 加上括号()以后依然会报错,因为分组操作符需要包含表达式

function foo(){ /* code */ }(); // SyntaxError: Unexpected token )

// 但是如果你在括弧()里传入一个表达式,将不会有异常抛出
// 但是foo函数依然不会执行
function foo(){ /* code */ }( 1 );

// 因为它完全等价于下面这个代码,一个function声明后面,又声明了一个毫无关系的表达式:
function foo(){ /* code */ }

( 1 );

你可以访问ECMA-262-3 in detail. Chapter 5. Functions 获取进一步的信息。

自执行函数表达式

要解决上述问题,非常简单,我们只需要用大括弧将代码的代码全部括住就行了,因为JavaScript里括弧()里面不能包含语句,所以在这一点上,解析器在解析function关键字的时候,会将相应的代码解析成function表达式,而不是function声明。

// 下面2个括弧()都会立即执行

(function () { /* code */ } ()); // 推荐使用这个
(function () { /* code */ })(); // 但是这个也是可以用的

// 由于括弧()和JS的&&,异或,逗号等操作符是在函数表达式和函数声明上消除歧义的
// 所以一旦解析器知道其中一个已经是表达式了,其它的也都默认为表达式了
// 不过,请注意下一章节的内容解释

var i = function () { return 10; } ();
true && function () { /* code */ } ();
0, function () { /* code */ } ();

// 如果你不在意返回值,或者不怕难以阅读
// 你甚至可以在function前面加一元操作符号

!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();

// 还有一个情况,使用new关键字,也可以用,但我不确定它的效率
// http://twitter.com/kuvos/status/18209252090847232

new function () { /* code */ }
new function () { /* code */ } () // 如果需要传递参数,只需要加上括弧()

上面所说的括弧是消除歧义的,其实压根就没必要,因为括弧本来内部本来期望的就是函数表达式,但是我们依然用它,主要是为了方便开发人员阅读,当你让这些已经自动执行的表达式赋值给一个变量的时候,我们看到开头有括弧(,很快就能明白,而不需要将代码拉到最后看看到底有没有加括弧。


JavaScript:立即执行的函数表达式的更多相关文章

  1. [javascript]IIFE立即执行的函数表达式

    近况:最近一直忙着找实习没有更新,不过学习还是在继续的.最近在写Node.js又稍带把javascript的角落知识捡了一遍,过半个月打算去看看python和一些CSS深层的书和博客.工作找的还好,拿 ...

  2. Javascript自执行匿名函数(function() { })()的原理浅析

    匿名函数就是没有函数名的函数.这篇文章主要介绍了Javascript自执行匿名函数(function() { })()的原理浅析的相关资料,需要的朋友可以参考下 函数是JavaScript中最灵活的一 ...

  3. javascript立即调用的函数表达式N种写法(第二篇)

    原文:javascript立即调用的函数表达式N种写法(第二篇) 上一篇博客我谈到将函数声明转换为函数表达式最常见的一种写法是:通过括号()将匿名函数声明转换为函数表达式即(function(){}) ...

  4. IIFE 立即执行的函数表达式

    介绍IIFE IIFE的性能 使用IIFE的好处 IIFE最佳实践 jQuery优化 在Bootstrap源码(具体请看<Bootstrap源码解析>)和其他jQuery插件经常看到如下的 ...

  5. 笔记:IIFE 立即执行的函数表达式 +function ($) { }(window.jQuery);

    在Bootstrap源码(具体请看<Bootstrap源码解析1>)和其他jQuery插件经常看到如下的写法: +function ($) { }(window.jQuery); 这种写法 ...

  6. Javascript自执行匿名函数(function() { })()的原理分析

    匿名函数指没有指定函数名或指针的函数,自执行匿名函数只是其中一种,下文中称这种函数为:自执行函数 下面是一个最常见的自执行函数: // 传统匿名函数 (function() { alert('hell ...

  7. 理解JavaScript的立即调用函数表达式(IIFE)

    首先这是js的一种函数调用写法,叫立即执行函数表达式(IIFE,即immediately-invoked function expression).顾名思义IIFE可以让你的函数立即得到执行(废话). ...

  8. javascript自执行匿名函数

    1)自执行匿名函数: 常见格式:(function() { /* code */ })(); 2)作用:       function中的code代码在解释时就已经在运行了.因此可以用它创建命名空间, ...

  9. javascript笔记05:函数表达式和函数语句的区别

    1.首先是函数语句: myfunc(); function myfunc() { //执行一些语句 } 当函数语句被定义的时候,在一个脚本代码被优先考虑,因此,无论该函数是定义之前或者定义之后都可以被 ...

随机推荐

  1. HtmlHelper使用大全

    许多时候我们会遇到如下场景在写一个编辑数据的页面时,我们通常会写如下代码1:<inputtype ="text" value='<%=ViewData["ti ...

  2. Linux- Nginx简单的负载均衡(一)

    这里先进行简单的nginx负载,安装nginx这里就不多说了,我们情景假设在已经安装好了nginx上: 1)查询nginx中的upstrea负载均衡模块  默认是有安装的.进入nginx源码目录中 . ...

  3. 面试题整理:C#(二)

    1.类,接口的区别 从定义的角度类描述一个实体,包括状态.属性和动作接口定义一类动作,没有实现,也没有状态信息从程序的角度接口是函数声明:类是函数实现接口可以有属性,不能有字段一个子类只能继承一个父类 ...

  4. 每日Scrum(3)

    冲刺第三天,团队重心还是在于把软件变得更加的高大上加上狂拽炫酷...内部功能呈现的多元化和吸引力是我们追求的目标: 问题出现的毫无疑问是创意,借鉴其他的类似软件和好的创意是最近的工作重心.

  5. Java Gradle入门指南之内建与定制任务类(buildSrc、Groovy等)

        上一篇随笔介绍了Gradle的安装与任务管理,这篇着重介绍Gradle的内建任务(in-built tasks)与自定义任务(custom tasks),借助Gradle提供的众多内建任务类型 ...

  6. Windows搭建python开发环境,python入门到精通[一]

    从大学开始玩python到现在参加工作,已经有5年了,现在的公司是一家.net的公司用到python的比较少,最近公司有新项目需要用到python,领导希望我来跟其他同事training,就有了这篇博 ...

  7. mysql错误一例:ERROR 1030 (HY000): Got error 28 from storage engine

    在使用mysqldump导出一份建库脚本是,发生了下面的错误: 当执行 desc table_name; 时也报错: tag为表名,show index from tag;倒是可以执行. 其实真正的错 ...

  8. 设计模式C#实现(十一)——组合模式

    意图 0 适用性 1 结构 2 实现 3 效果 4 意图 将对象组合成树形结构以表示“部分-整体”的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 适用性 你想表示对象的部 ...

  9. 金士顿U盘,群联PS2251-60主控,量产还原教程

    还原成一个可移动磁盘教程,只是在"分区设置"中将 "模式=21" 改为 "模式=3" 即可. 1. 打开:"MPALL_F1_90 ...

  10. VC++ Debug编译方式

    字节填充 VC++在Debug编译方式下,new的内存用0xcd(助记词为Cleared Data)填充,防止未初始化: delete后,内存用0xdd(Dead Data)填充,防止再次被使用. 这 ...