Javascript函数

一、函数类型

ECMAScript中包含三类函数,每一类都有各自的特性
1、函数声明:

  • 拥有函数名
  • 代码位置:全局上下文或者另外一个函数体中
  • 创建时间:在进入上下文时创建
  • 会影响变量对象
  • 声明方式如下:

    function add(a,b){
       return a + b;    
     }
    

    这类函数的主要特性是:只有它们可以影响变量对象(存储在上下文VO中)。
    2、函数表达式:

  • 代码位置位于表达式的位置
  • 名字可有可无
  • 不会影响变量对象
  • 在代码执行阶段创建
    这类函数的主要特性是:代码总是处于表达式的位置。最简单的示例如下:

      var foo = function(a,b){
            return a + b;
      }   
    

    3、函数声明 VS 函数表达式
    当函数表达式有名字的时候,它很难和FD区分。不过如果仔细看这两者定义的话,要区分它们还是很容易的:
    函数表达式总是处于表达式的位置。

      //在括号(分组操作符)只可能是表达式  
      (function foo(){});  
    
      //数组初始化中,同样也只能是表达式  
      [function bar(){}];  
    
      //逗号操作符也只能是表达式  
      1,function baz(){}  
    

    定义中还提到函数表达式是在执行代码阶段创建,并且不是存储在变量对象上。

      //不论是在定义前还是定义后,函数表达式都访问不到  
      //(因为它在代码执行的阶段创建)  
    
      alert(foo);//"foo" is not defined   
    
      (function foo(){});  
    
      //后面也没有用,因为它根本不存在VO中  
    
      alert(foo);//"foo" is not defined    
    

    4、立即执行函数

        方式一:  
        (function (){})();  
        方式二:  
        (function (){}());  
    

    二、函数创建的算法

    如下所示使用伪代码表示函数创建的算法(不包含联合对象的步骤)。有助于理解ECMAScript中的函数对象,此算法对所有函数类型都是一样的。

        F = new NativeObject();  
    
        //属性[[Class]] is "Function"  
        F.[[Class]] = "Function"  
    
        //函数对象的原型  
        F.[[Prototype]] = Function.prototype  
    
        //对函数自身引用  
        //[[Call]]在函数调用F()激活  
        //同时创建一个新的执行上下文  
        F.[[Call]] = <reference to function>  
    
        //内置的构造器  
        //[[Construct]]会在使用"new"关键字的时候激活  
        //事实上,它会为新对象申请内存  
        //然后调用F.[[Call]]来初始化创建的对象,将this值设置为新创建的对象  
        F.[[Construct]] = internalContructor  
    
        //当前上下文(创建函数F的上下文)的作用域链  
        F.[[Scope]] = activeContext.Scope  
        //如果是通过new Function()方式来创建,则  
        F.[[Scope]] = globalContext.Scope  
    
        //形参个数  
        F.length = countParameters  
    
        //通过F创建出来的对象的原型  
        __objectPrototype = new Object();  
        __objectPrototype.constructor = F   
    
        F.prototype = __objectPrototype  
    
        return F  
    

    要注意的是,F.[[Prototype]]是函数(构造器)的原型,而F.prototype是通过该函数创建出来的对象的原型。在有些文章中会将F.prototype叫做”构造器的原型”,这是错误的。

Fork me on GitHub