(转载)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 相关文章推荐
随机显示经典句子或诗歌的javascript脚本
Aug 04 Javascript
获取dom元素那些讨厌的位置封装代码
Jun 23 Javascript
jquery入门—编写一个导航条(可伸缩)
Jan 07 Javascript
浅谈js的setInterval事件
Dec 05 Javascript
JavaScript获得当前网页来源页面(即上一页)的方法
Apr 03 Javascript
纯JS焦点图特效实例(可一个页面多用)
Dec 07 Javascript
详解Vue中状态管理Vuex
May 11 Javascript
详解Vue打包优化之code spliting
Apr 09 Javascript
Js通过AES加密后PHP用Openssl解密的方法
Jul 12 Javascript
Vue使用mixin分发组件的可复用功能
Sep 01 Javascript
基于JavaScript实现十五拼图代码实例
Apr 26 Javascript
解决vue-router的beforeRouteUpdate不能触发
Apr 14 Vue.js
阻止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
php实现Mongodb自定义方式生成自增ID的方法
2015/03/23 PHP
php+ajax实现带进度条的上传图片功能【附demo源码下载】
2016/09/14 PHP
PHP实现动态删除XML数据的方法示例
2018/03/30 PHP
浅谈Laravel中的三种中间件的作用
2019/10/13 PHP
php变量与字符串的增删改查操作示例
2020/05/07 PHP
通用于ie和firefox的函数 GetCurrentStyle (obj, prop)
2006/12/27 Javascript
WEB页子窗口(showModalDialog和showModelessDialog)使用说明
2009/10/25 Javascript
js页面滚动时层智能浮动定位实现(jQuery/MooTools)
2011/08/23 Javascript
Prototype源码浅析 Enumerable部分(二)
2012/01/18 Javascript
无缝滚动改进版支持上下左右滚动(封装成函数)
2012/12/04 Javascript
php利用curl获取远程图片实现方法
2015/10/26 Javascript
浅谈jquery中的each方法$.each、this.each、$.fn.each
2016/06/23 Javascript
javascript超过容器后显示省略号效果的方法(兼容一行或者多行)
2016/07/14 Javascript
AngularJS基础 ng-mouseenter 指令示例代码
2016/08/02 Javascript
JavaScript中捕获与冒泡详解及实例
2017/02/03 Javascript
微信小程序 POST请求的实例详解
2017/09/29 Javascript
react-native封装插件swiper的使用方法
2018/03/20 Javascript
Vue 项目中遇到的跨域问题及解决方法(后台php)
2018/03/28 Javascript
Vue2.0 实现歌手列表滚动及右侧快速入口功能
2018/08/08 Javascript
JS数组求和的常用方法总结【5种方法】
2019/01/14 Javascript
在vue+element ui框架里实现lodash的debounce防抖
2019/11/13 Javascript
Jquery属性的获取/设置及样式添加/删除操作技巧分析
2019/12/23 jQuery
es6中class类静态方法,静态属性,实例属性,实例方法的理解与应用分析
2020/02/15 Javascript
vue实现信息管理系统
2020/05/30 Javascript
2分钟实现一个Vue实时直播系统的示例代码
2020/06/05 Javascript
Python之eval()函数危险性浅析
2014/07/03 Python
Python中用于去除空格的三个函数的使用小结
2015/04/07 Python
简介Django中内置的一些中间件
2015/07/24 Python
简单了解Python write writelines区别
2020/02/27 Python
Python脚本实现监听服务器的思路代码详解
2020/05/28 Python
python Socket网络编程实现C/S模式和P2P
2020/06/22 Python
Smashbox官网:美国知名彩妆品牌
2017/01/05 全球购物
国外最大的眼镜网站:Coastal
2017/08/09 全球购物
岗位竞聘演讲稿
2014/01/10 职场文书
幽默自我介绍演讲稿
2014/08/21 职场文书
顶岗实习计划书
2015/01/16 职场文书