js立即执行函数: (function ( ){})( ) 与 (function ( ){}( )) 有什么区别?

news/2024/7/19 14:31:33 标签: js, 前端

没有区别。

你需要明白 IIFE 的原理,我简单说一下:

复制代码代码如下:


function foo() {...}     // 这是定义,Declaration;定义只是让解释器知道其存在,但是不会运行。
foo();                   // 这是语句,Statement;解释器遇到语句是会运行它的。

IIFE 并非必须,传统一点可以这么写:

复制代码代码如下:


function foo() {...}
foo();

那么为什么要 IIFE?
1.传统的方法啰嗦,定义和执行分开写;
2.传统的方法直接污染全局命名空间(浏览器里的 global 对象,如 window)

于是,开发者们想找一个可以解决以上问题的写法。那么像下面这么写行不行呢?

function foo(...){}();

当然是不能,但是为什么呢?因为 function foo(...){} 这个部分只是一个声明,对于解释器来说,就好像你写了一个字符串 "function foo(...){}",它需要使用解析函数,比如 eval() 来执行它才可以。所以把 () 直接放在声明后面是不会执行,这是错误的语法。

如何把它变得正确?说起来也简单,只要把 声明 变成 表达式(Expression) 就可以了。

实际上转变表达式的办法还是很多的,最常见的办法是把函数声明用一对 () 包裹起来,于是就变成了:

复制代码代码如下:


(function foo() {...})    // 这里是故意换行,实际上可以和下面的括号连起来
();

这就等价于:

复制代码代码如下:


var foo = function () {...};    // 这就不是定义,而是表达式了。
foo();

但是之前我们说不行的那个写法,其实也可以直接用括号包起来,这也是一种等价的表达式:

(function foo(){...}());

所以你问有没有区别?很简单:木有~

另外,刚才说过转变表达式的方式很多,的确还有很多别的写法,比如:

!function foo() {...}();

或者

+function foo() {...}();

这些都可以。

我个人挺偏爱用 void 来转变表达式,因为此关键字不会有返回值。不过这一点真的没有什么要紧的,就当我“龟毛”好了……

复制代码代码如下:


void function () {
    // 这里是真正需要的代码
}();

OK,所谓不去污染全局命名空间,是因为 IIFE 创建了一个新的函数作用域,你真正的业务代码被封装在其中,自然就不会触碰到全局对象了。如果你需要全局对象,那就 pass 给 IIFE:

复制代码代码如下:


void function (global) {
    // 在这里,global 就是全局对象了
}(this)    // 在浏览器里,this 就是 window 对象

我在这里写过一个系列,其中一篇讲作用域和命名提升的,里面的知识点对理解 IIFE 有帮助,有兴趣的话可以继续深入阅读:https://www.jb51.net/article/75090.htm

方式一,调用函数,得到返回值。强制函数直接量执行再返回一个引用,引用在去调用执行
方式二,调用函数,得到返回值。强制运算符使函数调用执行
(function(){})(); 是 把函数当作表达式解析,然后执行解析后的函数
相当于 var a = function(){}; a(); a得到的是函数
(function(){}()); 是把函数表达式和执行当作语句直接执行、
相当于 var a = function(){}(); a得到的是结果
最终结果是一样的、
()只是起了 自执行的作用
和 () 一样的还有很多
比如 +function (){}
这个等于 (function (){}) 一般用(function (){}) 还有个作用,就是 避免全局变量


http://www.niftyadmin.cn/n/1869979.html

相关文章

黑马高薪学习方法

原文地址:http://bbs.itheima.com/forum.php?modviewthread&tid63387&extrapage%3D1 此文章是黑马老学员给新学员的学习建议,一个来自高薪学员的心声,望仔细耐心看完,这将是你在黑马学习的重要指南。 四个半月的时光转瞬…

AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式

HTTP请求中,如果是get请求,那么表单参数以namevalue&name1value1的形式附到url的后面,如果是post请求,那么表单参数是在请求体中,也是以namevalue&name1value1的形式在请求体中。通过chrome的开发者工具可以看…

JSP与SERVLET的关系

原文地址:http://blog.csdn.net/frank3g/article/details/4593426 综述:Java Servlet是JSP技术的基础,而且大型的Web应用程序的开发需要Java Servlet和JSP配合才能完成。现在许多Web服务器都支持Servlet,即使不直接支持Servlet的Web服务器&…

什么是 ant----编译打包工具 ant

原文地址:http://www.cnblogs.com/avenxia/archive/2011/12/08/2280701.html Apache Ant™ Apache Ant is a Java library and command-line tool whose mission is to drive processes described in build files as targets and extension points dependent upon each other. …

Myeclipse 导入 tomcat 源码

原文地址:http://blog.csdn.net/wwbmyos/article/details/7565617?reload 第一步: 下载源码,解压Tomcat源码,例如解压到D:\tomcat\apache-tomcat-6.0.33-src。 第二步: 2.1)使用ant编译tomcat源码,在编译…

使用 eclipse时,出现如下问题:org.eclipse.swt.SWTError: No more handles的解决办法

使用 eclipse时,出现如下问题,log如下 !ENTRY org.eclipse.osgi 4 0 2009-07-30 15:49:55.671 !MESSAGE Application error !STACK 1 org.eclipse.swt.SWTError: No more handles at org.eclipse.swt.SWT.error(SWT.java:3803) at org.eclipse.swt.gra…

input type=“submit“ 和“button“有什么区别?

在一个页面上画一个按钮&#xff0c;有四种办法&#xff1a; <input type"button" /> 这就是一个按钮。如果你不写javascript 的话&#xff0c;按下去什么也不会发生。<input type"submit" /> 这样的按钮用户点击之后会自动提交 form&#xf…

rose将图导出图片

方法一 &#xff1a;针对每一张绘制好的uml图形&#xff0c;使用ctrl-a ctrl-c 最后打开word, 执行ctrl-v就可以了&#xff0c;一般这种情况下是可以将每张图都粘贴到文档中然后就可以发送给他人共享了。 如果中文乱码 ctrlA全部选中&#xff0c;右键Format->Font 把字体…