Fork me on GitHub

定义函数的方式有三种:

  • 关键字function来定义
  1.   函数声明语句 function f(){}
  2.   函数定义表达式:常用形式:var f = function(){};   //这里的分号不能少
  • 使用构造函数Function: var f = new Function(),里面传入参数,最后一个参数默认为函数体,前面的参数则为函数的参数。(不建议使用这种方法,因为这种方法会导致解析两次代码,1:常规解析EMCAscript代码,2:解析传入构造函数中的字符串,从而会影响性能。)

     eg: var sum = new Function(“num1", "num2", "return num1 + num2");

 使用前两种方式定义该函数:

  • function sum(num1, num2){return num1 + num2;}
  • var sum = function(num1, num2){return num1 + num2;};

使用函数声明语句和函数定义表达式都包含三部分:

  1. 函数名称标识符,即funcName,但二者对其要求不一样,声明语句是必须要的,而函数定义表达式则是可选的,通常是省略的。
  2. 一对圆括号()。
  3. 一对花括号{}。

所以上面两种形式其实是这样的:

  • 声明语句:function funcName(x){},  对于声明语句,实际上会声明一个funcName变量,并把函数对象赋值给它。
  • 函数定义表达式 :function funcName(x){},     函数定义表达式并没有声明一个变量,这里的funcName就是可选的(optional),(如果存在funcName,函数的局部作用域会包含一个绑定到该函数对象的名称,即funcName,funcName就指代函数对象,且值存在于函数体内部,也就是函数名就成为函数的一个局部变量.),通常函数定义表达式只适用于作为一个大的表达式的一部分:比如赋值,或者调用,所以就有了:var s = function funcName(x){};通常省略该函数名,即出现常见的 var s = function(x) {};  通常在递归时函数表达式的名称很有用,如 
    var f = function fact(x){
        if(x <=1){
            return 1;
        }else {
            return x * fact(x-1);   //递归使用该函数
        }
    }

     

这两种定义方式都会创建一个新的函数对象。函数名实际上是一个指向该函数对象的指针,而不会与某个函数绑定。

 意思就是呢,函数体就在那里,不会动,可以通过函数名来引用该函数进行操作,两者其实是相对独立,但又有着某种关系。看下面例子:

1 function sum(num1,num2){
2     return num1 + num2;
3 }
4 alert(sum(10,10));   //20
5 
6 var anotherSum = sum;
7 alert(anotherSum(10,10));   //20
8 sum = null;
9 alert(anotherSum(10,10));    //20

这里的sum是函数名,可以通过sum引用到该函数,第6行将sum的值赋给anotherSum,这样anotherSum也可以访问到该函数体了,第8行将变量sum设为null,就是将它和函数体之间的关系切断,但函数体依然独立存在,不会受影响,从而anotherSum依旧可以引用到它,所以变量名就是一个指针而已。

 

理解完指针后,再来看看函数重载,EMACAScript里没有函数重载的概念,什么是重载呢?

 1 function addSomeNumber(num){
 2     return num + 100;
 3 }
 4 function addSomeNumber(num){
 5     return num + 300;
 6 }
 7 var result = addSomeNumber(100);  //400
 8 

//换一种方式: 9 var addSomeNumber = function(num){ 10 return num + 100; 11 }; 12 addSomeNumber = function(num){ 13 return num + 300; 14 }; 15 16 var result = addSomeNumber(100); //400

所以没有重载其实就是,覆盖函数引用,当创建了第二个函数体时,函数名就会指向新创建的函数体,从而覆盖之前引用的函数体,

 

函数声明与函数定义表达式的不同:

主要的不同是函数声明提前,有点像使用var 定义变量时,变量声明会提前,但初始化仍在原位置,但函数声明会让函数名和函数体都提前,将它们添加到执行环境中去,所以在声明该函数前就可以使用该函数。而函数定义表达式则不能提前,必须要执行到它后才会有效。

alert(sum(10,10));          //这里就声名提前了,
function sum(num1,num2){
    return num1 + num2;
}

alert(sum(10,10));           //这里就会出现错误
var sum = function(num1, num2){
    return num1 + num2;
};

二者的区别就是什么时候可以访问到函数。其他都是等价的。

 12:45:22、、2016-01-10

 posted on 2016-01-10 12:46  六人行与  阅读(218)  评论(0编辑  收藏  举报