Javacript中(function(){})() 与 (function(){}()) 区别 {转}
这个问题可以从不同的角度来看,但从结果上来说 :他们是一样的。
首先,如果从AST(抽象语法树)的角度来看,两者的AST是一模一样的,最终结果都是一次函数调用。因此,就解析器产生的结果论而言,两者是没有区别的。
其次 ,从作用上看,前文已经说了,两者的作用都是创建一个函数并调用之。
那么为什么要创建一个函数并立即调用呢,我想大多数是因为javascript的代码默认在全局环境下执行,在此声明的所有变量都会变成全局变量,这很容易导致全局对象的污染。因此我们不得不找一个办法来隔离这些变量,而函数正好会创建属于自己的作用域,因此创建一个匿名函数并立即调用(有称此为IIFE-Immediately Invoked Function Exprssion-立即调用的函数表达式)成为了一种几乎公认的方案。
随后,又为什么要这么写呢?原因自然是在javascript中有2个语法都与function关键字有关,分别是:
函数定义:function FunctionName(FormalParameterList) { FunctionBody }
函数表达式:function [FunctionName](FormalParameterList) { FunctionBody }
从语法的定义上看,这两者几乎是一模一样的(唯一的区别是函数表达式可以省略函数名称),那么就解释器而言,当遇到这个结构的语句时,判定为函数表达式还是函数定义呢?
就javascript的语法而言,如果一条语句是以function关键字开始,那么这段会被判定为函数定义。而函数定义是不能被立即执行的,这无疑会导致语法的错误(SyntaxError),因此就必须有一个办法,使解析器可以将之识别为函数表达式。
前面已经说到,解析器识别函数定义的条件是以function关键字开始,那么自然,只要在function关键字的前面有任何其他的元素,就会从函数定义转变为函数表达式,以下方法都是可以的,这个大家都知道:
~function() {}();
!function() {}();
void function() {}();
但是这几个方法都有一个特点,就是看起来很别扭,所以现在为止,以括号包裹成了比较公认的方案。
回到正题,括号包裹同样有2个方式:(function() {})();和(function(){}());
他们的共通点是:都有括号。而括号在javascript中有2种作用:确立运算优先级,以及分组运算符(http://es5.github.com/#x11.1.6),从代码上看,显然没有进行数学或逻辑运算,因此我认为这里的括号属于分组运算符。
根据标准,分组运算符的作用是:
Return the result of evaluating Expression. This may be of type Reference.
返回评估括号中的表达式的结果。结果可能是Reference类型。
抛开像Reference类型这种词汇,这里的一个关键词应当是“ 评估 ”(对evaluate的翻译一直把握不好,姑且这么叫吧),但是关于分组运算符,又有一个很重要的下文:
This algorithm does not apply GetValue to the result of evaluating Expression.
这个算法不会对估算的结果使用GetValue。
有很多专用的名词,看起来确实复杂,简而言之,使用括号运算符本身不会让括号中的代码立即执行,只有当括号包含的这个“分组”参与其他运算时,才会执行。因此,(function(){})()这个语句,其实是首先用分组运算符评估了一个函数表达式,随后参与“函数调用”。而(function(){}())这个语句,则是用分组运算符评估了一个函数调用,随后由于语句的结束而被执行。从语句上来说有细微的差距,当然就结果而言是一样的,最初的AST分析也可以证实这点,分组运算符在AST中完全没有体现出来。
Javacript中(function(){})() 与 (function(){}()) 区别 {转}的更多相关文章
- JavaScript 中,定义函数时用 var foo = function () {} 和 function foo() {}有什么区别?
对于新手来说(本人也是新手-_-!),好像var foo = function () {} 和 function foo(){}并没有什么区别,意识里可能就认为就是两种不同的写法而已.但是,通过网上查 ...
- VB.NET中Sub和Function的区别
function是函数,sub是子程序,都可以传递参数,但函数有返回值,子程序没有 function 可以用自身名字返回一个值,sub 需定义别的变量,用传址方式传回值. Sub 过程与Functio ...
- js中(function(){}()),(function(){})(),$(function(){});之间的区别
1. (function(){}())与(function(){})() 这两种写法,都是一种立即执行函数的写法,即IIFE (Immediately Invoked Function Express ...
- jQuery中$(function(){})与(function($){})(jQuery)、$(document).ready(function(){})等的区别详细讲解
1.(function($) {…})(jQuery); 1).原理: 这实际上是匿名函数,如下: function(arg){…} 这就定义了一个匿名函数,参数为arg 而调用函数时,是在函数后面写 ...
- jQuery中$(function(){})与(function($){})(jQuery)、$(document).ready(function(){})等的区别详细讲解 ----转载
1.(function($) {-})(jQuery); 1).原理: 这实际上是匿名函数,如下: function(arg){-} 这就定义了一个匿名函数,参数为arg 而调用函数时,是在函数后面写 ...
- jQuery中$(function(){})与(function($){})(jQuery)、$(document).ready(function(){})等的区别详解
1.(function($) {…})(jQuery); 1).原理: 这实际上是匿名函数,如下: function(arg){…} 这就定义了一个匿名函数,参数为arg 而调用函数时,是在函数后面写 ...
- jQuery中$(function(){})与(function($){})(jQuery)、$(document).ready(function(){})等的区别讲解
1.(function($){...})(jQuery); (1).原理: 这实际上是匿名函数,如下: function(arg){...} 这就定义了一个匿名函数,参数为arg:而调用函 ...
- 浅析jQuery(function(){})与(function(){})(jQuery)之间的区别
本篇文章主要是对jQuery(function(){})与(function(){})(jQuery)之间的区别进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助 Jquery是优秀的Javas ...
- function foo(){}、(function(){})、(function(){}())等函数区别分析
前面一段时间,看到(function(){}),(function(){}())这些函数就犯晕,不知道它到底是什么意思,为什么函数外要加小括号,函数后要加小括号,加和不加到底有什么区别……一直犯迷糊, ...
随机推荐
- linux网络子系统内核分析
1.选择路由 若要将数据包发至PC2,则linux系统通过查询路由表可知168.1.1.10(目的地址)的网关地址为192.168.1.1,此时linux系统选择网卡1发送数据包. 2.邻居子系统(通 ...
- wpf 在引用外部的资源字典
启动的APP.xaml
- Excle快速输入√与×
如何在EXCLE中快速输入√与×呢 很简单的一个小技巧,只需要在EXCLE单元格中输入P(O) 然后将其字体设置为Wingdings 2,接着就出现符号了 不信你可以试试的哦.
- Sql Server 语句
##目录 #####清除缓存 DBCC FREEPROCCACHE; DBCC DROPCLEANBUFFERS; SELECT stock.IdStock, stock.Descr FROM [In ...
- linux中fork()函数详解
一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...
- Android的快速开发框架afinal
afinal 是一个android的 orm 和 ioc 框架.而且封装了android中的httpClient,使其更加简单易用. afinal是android应用开发的终极框架. FinalDB使 ...
- microsoft azure 速度测试网址
http://www.azurespeed.com/ 选择你附近的区域.可以使用 azurespeed.com 查找延迟最低的数据中心.
- 用Swift重写公司OC项目(Day2)--创建OC与Swift的桥接文件,进而调用OC类库
昨天把项目中的图标以及启动转场图片弄好了,那么今天,我们可以开始慢慢进入到程序的编写当中了. 由于swift较新,所以类库还不够完善,但是不用担心,苹果早就出了解决方案,那就是使用桥接文件,通过桥接文 ...
- 自定义Drawable
本文由 伯乐在线 - treesouth 翻译,toolate 校稿.未经许可,禁止转载! 英文出处:ryanharter.com.欢迎加入翻译小组. 我们看过一些博客文章,讲述了为什么要适时地使用自 ...
- Client–server model
Client–server model From Wikipedia, the free encyclopedia The client–server model of computing ] Oft ...