(转载)JavaScript中匿名函数,函数直接量和闭包


Posted in Javascript onMay 08, 2007

原文出处: http://www.dnew.cn/post/196.htm

先看下下面几种写法

1.function f(x){return x*x;};f(x);

2.(function(x){return x*x;})(x);

3.(function(x){return x*x;}(x));

第一种我们应该都很熟悉了,这是我们经常使用的写法。第二第三种都是匿名函数的写法。

--------------------------------------------------------------------------------

第二种
可以这样理解:

var f=function(x) {return x*x;};f()

那我们不通过f这个变量来引用函数就是

function(){}()

然而这样肯定是错误的就像

var f=1+2;
f=f*0;

var f=1+2*0;

结果不同一样。
要得到正确结果只能:

f=(1+2)*0;

也就是要明确的标识出程序块,即:

(function(){})()

肯你有疑问:括号“()”到底是不是起到了标识代码块的作用?
我们可以用JavaScript的内置函数检测一下!
举一个最简单的例子:

alert(4)

这段代码会弹出提示内容是“4”
改成这样
(alert)(4)

可以看到执行的效果和上一段代码一样。

这种形式的函数执行也被很多JavaScript框架所采用。

--------------------------------------------------------------------------------

第三种,如果你用过jsvm框架的话就会发现里面的代码使用了这种形式。
那如何解释第三种情况呢?
为了弄明白浏览器是如何理解这样的写法的,我们可以利用一下Mozilla Firefox的错误控制台功能。
在代码中插入一段错误代码,代码段如下:

(function(s){s+s}(1)).splice();

打开Mozilla Firefox的错误控制台,可以看到有如下的错误提示

错误: (function (s) {})(1) has no properties
源文件:file:///C:/Documents…….html
行:18

可以认为,浏览器对于
(function(s){s+s}(1))
这样的代码按照

(function (s) {s+s})(1)
来解析的。

--------------------------------------------------------------------------------

到此可能你有这样的认识:

function f(x){return x*x;};f(x);==(function(x){return x*x;})(x);==(function(x){return x*x;}(x));

但是他们还是有区别的,
首先,对于像第二和第三种形式,其它的函数和代码是不可能调用所定义的函数的,有一种说发把这样的函数称为匿名函数或者函数直接量。
其次,第二和第三种形式执行的函数,中间变量不会污染到全局命名空间,你可以把中间的代码看作纯粹的子过程调用。
当然使用后面两种形式的函数定义可以很容易的实现闭包。
看一个例子:

/*
http://jibbering.com/faq/faq_notes/closures.html(Dnew.CN注)
A global variable - getImgInPositionedDivHtml - is declared and
  assigned the value of an inner function expression returned from
  a one-time call to an outer function expression.

  That inner function returns a string of HTML that represents an
  absolutely positioned DIV wrapped round an IMG element, such that
  all of the variable attribute values are provided as parameters
  to the function call:-
*/
var getImgInPositionedDivHtml = (function(){
   /* The - buffAr - Array is assigned to a local variable of the
      outer function expression. It is only created once and that one
      instance of the array is available to the inner function so that
      it can be used on each execution of that inner function.

      Empty strings are used as placeholders for the date that is to
      be inserted into the Array by the inner function:-
   */
   var buffAr = [
       '<div id="',
       '',   //index 1, DIV ID attribute
       '" style="position:absolute;top:',
       '',   //index 3, DIV top position
       'px;left:',
       '',   //index 5, DIV left position
       'px;width:',
       '',   //index 7, DIV width
       'px;height:',
       '',   //index 9, DIV height
       'px;overflow:hidden;\"><img src=\"',
       '',   //index 11, IMG URL
       '\" width=\"',
       '',   //index 13, IMG width
       '\" height=\"',
       '',   //index 15, IMG height
       '\" alt=\"',
       '',   //index 17, IMG alt text
       '\"><\/div>'
   ];
   /* Return the inner function object that is the result of the
      evaluation of a function expression. It is this inner function
      object that will be executed on each call to -
      getImgInPositionedDivHtml( ... ) -:-
   */
   return (function(url, id, width, height, top, left, altText){
       /* Assign the various parameters to the corresponding
          locations in the buffer array:-
       */
       buffAr[1] = id;
       buffAr[3] = top;
       buffAr[5] = left;
       buffAr[13] = (buffAr[7] = width);
       buffAr[15] = (buffAr[9] = height);
       buffAr[11] = url;
       buffAr[17] = altText;
       /* Return the string created by joining each element in the
          array using an empty string (which is the same as just
          joining the elements together):-
       */
       return buffAr.join('');
   }); //:End of inner function expression.
})();
/*^^- :The inline execution of the outer function expression. */

Javascript 相关文章推荐
jquery 入门教程 [翻译] 推荐
Aug 17 Javascript
js png图片(有含有透明)在IE6中为什么不透明了
Feb 07 Javascript
js动态控制table的tr、td增加及删除的具体实现
Apr 30 Javascript
jQuery操作元素css样式的三种方法
Jun 04 Javascript
a标签的href与onclick事件的区别详解
Nov 12 Javascript
使用js画图之饼图
Jan 12 Javascript
分享一个精简的vue.js 图片lazyload插件实例
Mar 13 Javascript
浅谈Angular路由复用策略
Oct 04 Javascript
微信小程序iOS下拉白屏晃动问题解决方案
Oct 12 Javascript
vue video和vue-video-player实现视频铺满教程
Oct 30 Javascript
jQuery使用hide()、toggle()函数实现相机品牌展示隐藏功能
Jan 29 jQuery
详解vite2.0配置学习(typescript版本)
Feb 25 Javascript
阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)
May 08 #Javascript
延时重复执行函数 lLoopRun.js
May 08 #Javascript
用js判断浏览器是否是IE的比较好的办法
May 08 #Javascript
[全兼容哦]--实用、简洁、炫酷的页面转入效果loing
May 07 #Javascript
javascript之水平横向滚动歌词同步的应用
May 07 #Javascript
javascript之ESC(第二类混淆)
May 06 #Javascript
通过Unicode转义序列来加密,按你说的可以算是混淆吧
May 06 #Javascript
You might like
使用Limit参数优化MySQL查询的方法
2008/11/12 PHP
深入解析PHP中逗号与点号的区别
2013/08/05 PHP
PHP中绘制图像的一些函数总结
2014/11/19 PHP
文本框的字数限制功能jquery插件
2009/11/24 Javascript
jquery中get,post和ajax方法的使用小结
2014/02/04 Javascript
chrome下jq width()方法取值为0的解决方法
2014/05/26 Javascript
node.js中的http.response.write方法使用说明
2014/12/14 Javascript
zepto中使用swipe.js制作轮播图附swipeUp,swipeDown不起效果问题
2015/08/27 Javascript
jquery通过扩展select控件实现支持enter或focus选择的方法
2015/11/19 Javascript
js实现网页收藏功能
2015/12/17 Javascript
使用Angular.js实现简单的购物车功能
2016/11/21 Javascript
Django使用多数据库的方法
2017/09/06 Javascript
浅谈JS函数节流防抖
2017/10/18 Javascript
Vue打包后出现一些map文件的解决方法
2018/02/13 Javascript
vue+element实现批量删除功能的示例
2018/02/28 Javascript
jQuery实现为动态添加的元素绑定事件实例分析
2018/09/07 jQuery
Element-ui之ElScrollBar组件滚动条的使用方法
2018/09/14 Javascript
vscode中eslint插件的配置(prettier配置无效)
2019/09/10 Javascript
[00:47]DOTA2荣耀之路6:玩不了啦!
2018/05/30 DOTA
跟老齐学Python之总结参数的传递
2014/10/10 Python
kNN算法python实现和简单数字识别的方法
2014/11/18 Python
详解Python的单元测试
2015/04/28 Python
python3操作mysql数据库的方法
2017/06/23 Python
Python Excel处理库openpyxl使用详解
2019/05/09 Python
Python生成器常见问题及解决方案
2020/03/21 Python
python和c语言哪个更适合初学者
2020/06/22 Python
python输出国际象棋棋盘的实例分享
2020/11/26 Python
一个J2EE项目团队的主要人员组成是什么
2012/06/04 面试题
行政专员工作职责
2013/12/22 职场文书
讲座主持词
2014/03/20 职场文书
房地产活动策划方案
2014/05/14 职场文书
公司总经理任命书
2014/06/05 职场文书
优秀高中学生评语
2014/12/30 职场文书
车间主任岗位职责
2015/02/03 职场文书
八年级语文教学反思
2016/03/03 职场文书
goland 恢复已更改文件的操作
2021/04/28 Golang