()()表达式立即执行的记录

了解过js的同学基本上都遇到过()()这种方式的函数体。一开始我也不懂这是啥,没见过啊,这特么到底是什么玩意?具体深入了解后,才知道这是匿名函数直接执行的一种写法。看过某些帖子上有一个经典的例子,在此记录下来。

这种方式叫函数的闭包(closure),可以让匿名函数立即被执行(最后面的那对括号就是让上面定义的匿名函数立即执行的秘密),这种闭包有以下几个优势或特点:
1. 减少了全局变量的个数,可以有效减少命名冲突
   原因是包在里面的变量对于外面来说是不可见的,他们的作用域近局限在匿名函数的函数体内
2. 这种方式可以保存闭包外面的变量的状态,这个特点还是举个例子比较易懂:

function fn() {
    for(var i=0 ; i<2; i++) {
    //(function(){
        var backup = i;
        setTimeout(function() {
            alert(backup);
        }, 2000);
    //})();
    }
}

fn();

  上面代码的for循环一共两次,我们本来的目的是每隔两秒钟把每一次循环的索引(也就是i)输出,我们期待它应该输出:0和1,但是实际输出结果却是两次都是1
使用了闭包之后,我们会把循环中每一次i值的状态都保存下来,如下代码所示:

function fn() {
    for(var i=0 ; i<2; i++) {
    (function(){
        var backup = i;
        setTimeout(function() {
            alert(backup);
        }, 2000);
    })();
    }
}

fn();

  这次我们得到了正确的结果:0和1。因为闭包引用的是父函数范围内的最终值。

括号表达式,写起来精简,另外匿名函数就执行了,不过这么写函数就没办法通用了。

最后再来看看下面这种写法,传参的一种形式。

function f() {
  var a = [];
  var i;
  for(i = 0; i < 3; i++) {
    a[i] = (function(i){
      return function(){
        alert(i);
        return i;
      }
    })();
  }
  return a;
}   

var a = f();
a[0]();//undefined
a[1]();//undefined
a[2]();//undefined
---------------------------
function f() {
  var a = [];
  var i;
  for(i = 0; i < 3; i++) {
    a[i] = (function(x){
      return function(){
        alert(x);
        return x;
      }
    })(i);
  }
  return a;
}   

var a = f();
a[0]();//0
a[1]();//1
a[2]();//2

  上面的代码可以得出一个结论。js中,表达式立即执行()()的这种写法可以表示为(匿名表达式)(需要传入的参数),即(function(arg1,arg2,...){})(arg1,arg2,...),能表达这种写法的最简便的代码如下:

(function(a,b,c){
    alert(a);
    alert(b);
    alert(c);
})(1,2,3);

//打印结果
//1
//2
//3

  

时间: 2024-10-26 07:58:16

()()表达式立即执行的记录的相关文章

celery 定时任务,使用crontab表达式不执行(版本4.3.x)

celery 定时任务,使用crontab表达式不执行(版本4.3.x) 在使用celery 执行定时任务时,发现任务不会执行,schedule设置如下: 经测试,如果去掉hour,则任务每分钟都会执行,说明是hour的问题,那只有是时区的问题了. 遂将hour改为UTC的时间,发现任务可以执行,说明celery使用的是UTC时区,但我设置的时区如下: CELERY_TIMEZONE='Asia/Shanghai' CELERY_ENABLE_UTC=True 注意添加任务的时候使用utc时间,

立即执行函数表达式(自执行函数)

立即执行函数表达式 立即执行函数表达式,大部分人也称为自执行函数. 自执行函数的写法 匿名函数 (function(){ console.log(2) })() 具名函数 (function log(){ console.log(2) })() 自执行函数的传参 (function add(a, b){ console.log(a + b) })(1,2) 返回值 let fn = (function add(a,b){ return a + b; })(2,4); console.log(fn

PIM-DM协议内核触发机制及协议执行机制记录

PIM-DM和PIM-SM是组播路由ASM(随意信源组播)中的两种不同模式.相对PIM-SM的组播注冊机制.PIM-DM的扩散机制显得更加粗犷. 一.PIM-DM无需向内核注冊pimreg虚接口. 可是同PIM-SM一样须要将三层接口增加MRT组播接口中. 以在内核收到组播报文后触发cache_miss消息. 二.协议初始化阶段,会创建PIM协议套接字和igmp套接字,igmp套接字通过配置相同能够接收来自内核的igmp组播控制报文(cache_miss.process_whole_packet

一次$.getJSON不执行的记录

别人的代码,拿过来调,发现修改功能都不能用,修改时通过ajax发json获取数据的,看chrome开发者工具发现有发送数据,也有返回值: 发起请求并获取数据,发现回调函数不执行! $.getJSON(site_url+'?m=test&a=getOne',{id:id},function(d){ if(d.status){ vardata=d.data; $('input[name="id"]').val(data.id); $('input[name="name&q

Java表达式的执行顺序

•表达式中各个操作数求值完成后要按照各个运算符的优先级进行计算 X+Y*Z •当表达式中的运算符的优先级相同时,要通过运算符的结合性来决定计算的顺序,运算符的结合性可分为左结合和右结合,除赋值运算符=外,其它的二元运算符都是左结合,条件运算符?:是右结合

JSP中EL表达式取值问题记录(未解决)

***************************2015-10-28 22:21************************* 问题描述如下: 在当前的jsp页面已经有了如下代码: <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getSe

Linux上用户执行命令记录

HFILE=`who -m | awk '{print $1}'`readonly HISTFILE=/var/history/$HFILE-$USER-$UID.logreadonly HISTFILESIZE=50000readonly HISTSIZE=10000readonly HISTTIMEFORMAT='%F %T 'readonly HISTCONTROL=ignoredupsshopt -s histappendreadonly PROMPT_COMMAND="history

【centOS】系统执行命令记录到message 日志文件中

直接 配置 /etc/profile 配置文件添加一样,简单高定. export PROMPT_COMMAND='{ msg=$(history 1 | { read x y; echo $y; });logger "[euid=$(whoami)]":$(who am i) [pwd] "$msg";}' 扩展性能,中文显示不乱码 ulimit -n 102400export LC_ALL=en_US.UTF-8 原文地址:https://blog.51cto.c

Entity Framework——记录执行的命令信息

有两种方法可以记录执行的SQl语句: 使用DbContext.Database.Log属性 实现IDbCommandInterceptor接口 一 使用DbContext.Database.Log属性 下面截图显示了Database属性和Log属性,可以看出这个属性是一个委托,类型为Action<string> 对Log属性的解释为: Set this property to log the SQL generated by the System.Data.Entity.DbContext t