(转载)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 相关文章推荐
js change,propertychange,input事件小议
Dec 20 Javascript
高效的获取当前元素是父元素的第几个子元素
Oct 15 Javascript
jQuery制作简洁的多级联动Select下拉框
Dec 23 Javascript
jQuery实现鼠标悬停背景翻转的黑色导航菜单代码
Sep 14 Javascript
JavaScript ParseFloat()方法
Dec 18 Javascript
jQuery焦点图插件SaySlide
Dec 21 Javascript
Javascript发送AJAX请求实例代码
Aug 21 Javascript
JQuery ZTree使用方法详解
Jan 07 Javascript
Vue如何引入远程JS文件
Apr 20 Javascript
js核心基础之构造函数constructor用法实例分析
May 11 Javascript
Vue3.0数据响应式原理详解
Oct 09 Javascript
浅析JS中NEW的实现原理及重写
Feb 20 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
Win9x/ME下Apache+PHP安装配置
2006/10/09 PHP
使用PHP生成二维码的两种方法(带logo图像)
2014/03/14 PHP
php实现socket推送技术的示例
2017/12/20 PHP
php基于协程实现异步的方法分析
2019/07/17 PHP
ExtJs默认的字体大小改变的几种方法(自己整理)
2013/04/18 Javascript
解析瀑布流布局:JS+绝对定位的实现
2013/05/08 Javascript
利用ajaxfileupload插件实现文件上传无刷新的具体方法
2013/06/08 Javascript
JS实现同时搜索百度和必应的方法
2015/01/27 Javascript
js获取页面description的方法
2015/05/21 Javascript
理解javascript中try...catch...finally
2015/12/25 Javascript
js实现浏览器倒计时跳转页面效果
2016/08/12 Javascript
解析预加载显示图片艺术
2016/12/05 Javascript
Bootstrap CSS布局之表单
2016/12/17 Javascript
AngularJS自定义指令详解(有分页插件代码)
2017/06/12 Javascript
jquery实现楼层滚动效果
2018/01/01 jQuery
浅谈在Vue.js中如何实现时间转换指令
2019/01/06 Javascript
js array数组对象操作方法汇总
2019/03/18 Javascript
详解vue页面首次加载缓慢原因及解决方案
2019/11/06 Javascript
vue实现把接口单独存放在一个文件方式
2020/08/13 Javascript
python逆向入门教程
2018/01/15 Python
Python检测网络延迟的代码
2018/05/15 Python
PyQt5实现五子棋游戏(人机对弈)
2020/03/24 Python
python 实现二维列表转置
2019/12/02 Python
python numpy数组中的复制知识解析
2020/02/03 Python
浅谈python 调用open()打开文件时路径出错的原因
2020/06/05 Python
Python OpenCV去除字母后面的杂线操作
2020/07/05 Python
python time.strptime格式化实例详解
2021/02/03 Python
施华洛世奇日本官网:SWAROVSKI日本
2018/05/04 全球购物
Joules官网:女士、男士和儿童服装和鞋类
2018/10/23 全球购物
开放系统互连参考模型
2016/06/29 面试题
一份关于丢失公司财物的检讨书
2014/09/19 职场文书
合作意向协议书
2015/01/29 职场文书
学生通报表扬范文
2015/05/04 职场文书
简爱电影观后感
2015/06/10 职场文书
论语读书笔记
2015/06/26 职场文书
HTML5页面音频自动播放的实现方式
2021/06/21 HTML / CSS