立即调用函数

  • 立即执行函数前面加分号是个好习惯,像这样子(function(){alert(1)})()的函数,如果js不换行,或者经过了压缩,很容易会使前后文重叠混乱。
  • 函数调用的两种方式,通过函数名调用,通过表达式调用。匿名函数调用算在表达式调用的方法里。
  • 而“function f(){}(1)”就是合法的,
    这个语句可以解读为两部分,第一部分还是function f(){}的函数声明,第二部分是(1)这个表达式;所以,函数没有被调用,运行结果为
    function f(){alert("fff")}(1)
    //1
  • “function f(){}”归约为FunctionDeclaration,
    “(1)”可以归约为Expression,视为括号运算符,或称为分组运算符。
  • 函数声明时必须有函数名
  • 构造函数并赋值

    var abc = new Function("x","y","return x*y;");
     
    alert(abc(2,3)); // "6"  

    alert((function(x,y){return x+y;})(2,3));// "5"  
    alert((new Function("x","y","return x*y;"))(2,3));// "6"

  • 小括号能把表达式组合分块,并且每一块,也就是每一对小括号,都有一个返回值。这个返回值实际上也就是小括号中表达式的返回值。所以,当我们用一对小括号把匿名函数括起来的时候,实际上小括号对返回的,就是一个匿名函数的Function对象。因此,小括号对加上匿名函数就如同有名字的函数般被我们取得它的引用位置了。所以如果在这个引用变量后面再加上参数列表,就会实现普通函数的调用形式。

  • (function(){alert(1)})()应该是与a=function(){alert(1)}()等价,不能连a=都去掉。
  • 所以如果问你那个开篇中的jQuery代码片段是应用了JS里的什么特性?那么它只是匿名函数与匿名函数的调用而已。但是,它隐含了闭包的特性,并且随时可以实现闭包应用。因为JS天生就是有这个特性的!

  • 闭包容易造成内存泄漏,闭包导致内部变量被外面引用,得不到释放

  • 使用严格模式时,建议按一个个函数去开启严格模式(至少在学习的过渡期要这样做)
  • function strict()
    {
      // 函数级别严格模式语法
      'use strict';
      function nested() { return "And so am I!"; }
      return "Hi!  I'm a strict mode function!  " + nested();
    }
    function notStrict() { return "I'm not strict."; }

     

  • void function(){alert(2)} //undefined 
    void function(){alert(2)}(); 可以调用
    new function(){alert(2)}();可以调用
    new function(){alert(2)}; 这里后面没跟括号,也可以调用。
    具体原因,在慢慢研究!!留个mark!

     

  • var nextId = function() { var id = 1 return function() { return id++ } },调用方式nextId();
    有些函数通常只会执行一次,比如进行初始化之类的工作。没必要浪费时间为它起一个可以复用的函数名
    var dd=function() { 
    alert("hello, world."); 
    } (); 在表达式后面加括号,可以调用



  • 现在,无论你定义一个函数像这样function foo(){}或者var foo = function(){},调用时,你都需要在后面加上一对圆括号,像这样foo()
  • JavaScript中()之间只能包含表达式(expression)由于把函数的声明写在了()之中,所以解释器以表达式(expression)来解析其中代码

  • foo相对于函数表达式`function(){/* code */}`只是一个引用变量
    
    var foo = function(){/* code */}
    function(){ /* code */}(); //SyntaxError: Unexpected token (
    
    遇到了这样的function关键字,默认的,它会将它当作是一个函数声明,而不是函数表达式,如果你不明确的告诉圆括号它是一个表达式,
    它会将其当作没有名字的函数声明并且抛出一个错误,因为函数声明需要一个名字。
    var foo = function(){console.log(1)}(),答案是可以的。
    //然而函数声明语法上是无效的,它仍然是一个声明,紧跟着的圆括号是无效的,因为圆括号里需要包含表达式。
    如果想要直接调用匿名函数,需要让js把它按照表达式来解析
    function foo(){ /* code */ }();//SyntaxError: Unexpected token //现在,你把一个表达式放在圆括号里,没有抛出错误...,但是函数也并没有执行,因为: function foo(){/* code */}(1) //它等同于如下,一个函数声明跟着一个完全没有关系的表达式: function foo(){/* code */} (1);
    当圆括号包裹函数时,它会默认将函数作为表达式去解析,而不是函数声明.
    (function(){/* code */}());//Crockford recommends this one,括号内的表达式代表函数立即调用表达式
    (function(){/* code */})();//But this one works just as well,括号内的表达式代表函数表达式
  • new function(){ alert("gg") } 会调用

  • 立即调用函数的一个优点,当这是一个非常长的函数表达式时,这可以节约比人阅读你代码的时间,不用滚到页面底部去看这个函数是否被调用。
  • 只要能让JavaScript解释器以「函数表达式」而不是「函数声明」来处理匿名函数的立即执行就可以了,把语句放在()之中只是其中的一种方法

  • // 如果本身就是expression,那么根本不需要做任何处理
    var i = function(){ return 10; }();
    true && function(){ /* code */ }();
    0, function(){ /* code */ }();
    
    // 如果你不在乎返回值,可以这么做
    !function(){ /* code */ }();
    ~function(){ /* code */ }();
    -function(){ /* code */ }();
    +function(){ /* code */ }();

    当圆括号出现在匿名函数的末尾想要调用函数时,它会默认将函数当成是函数声明。

    当圆括号包裹函数时,它会默认将函数作为表达式去解析,而不是函数声明。

 

原文地址:https://www.cnblogs.com/nostic/p/5769019.html