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(){}())这些函数就犯晕,不知道它到底是什么意思,为什么函数外要加小括号,函数后要加小括号,加和不加到底有什么区别……一直犯迷糊, ...
随机推荐
- DB2查询结果显示n行
在SQLserver中语法是这样的:select top n * from staff ,即可查询显示n行数据 但是在DB2中语法是这样的,感觉比较接近英语. select * from STAFF ...
- Node.js中的模块化
每天一篇文章来记录记录自己的成长吧.大二,该静心了.加油~ 好了,废话不多说,今天说说nodejs中的模块化.(注:此文为自己对书nodejs实战的总结) nodejs一个重要的特性就是模块化,模块就 ...
- UITextField使用的相关方法
1.设置占位符 textField.placeholder = @“”; 2.设置暗文输入 textField.secureTextEntry = YES; 3.设置键盘类型 textField. ...
- 2天驾驭DIV+CSS (实战篇)(转)
这是去年看到的一片文章,感觉在我的学习中,有不少的影响.于是把它分享给想很快了解css的兄弟们.本文是实战篇. 基础篇[知识一] “DIV+CSS” 的叫法是不准确的[知识二] “DIV+CSS” ...
- 在 Ubuntu 13.10 中搭建Java开发环境 - 懒人版
本文记录我在Ubuntu 13.10中搭建Java开发环境. 本文环境: Ubuntu 13.10 x64运行在Win7下的VMware Workstation 10中. 1. 安装JDK与JRE s ...
- MVC返回图片
这几天忙着一些小事,也没有写什么了,今天,我们来玩一个比较简单的东东.就是在MVC下如何返回图片,相信,在传统WebForm下,大家都晓得怎么弄,方也不限于一种,但是,在架构较为严格的MVC里面,刚开 ...
- 修改ip脚本
1.打开运行 2.输入CMD 3.在命令提示符下输入: netsh -c interface ip dump > C:\我的网络配置.txt 4.打开您在C:\ 下的"我的网络配置 . ...
- SetTmer函数调用 、取时间函数调用 、计时函数
SetTmer函数调用 #include <iostream> 取时间函数调用 计时函数
- C++中栈的出栈,入栈规则:A,B,C,D,E
考题: 栈底至栈顶一次存放元素 ABCD 在第五个元素E入栈之前 栈中元素可以出栈,则出栈序列可能是_____a d___________. a. ABCED b. DBCEA c. CD ...
- 团队开发(NABC)
特点:这是一个手机软件,能通过通讯录录入生日信息 N(Need需求):现在在交际圈中需要记住越来越多朋友的生日信息 A(Approach做法):由一个简单的闹钟为基础,添加与生日相关的功能,最终实现 ...