定义函数的方式有三种:
- 关键字function来定义:
- 函数声明语句 function f(){}
- 函数定义表达式:常用形式: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;};
使用函数声明语句和函数定义表达式都包含三部分:
- 函数名称标识符,即funcName,但二者对其要求不一样,声明语句是必须要的,而函数定义表达式则是可选的,通常是省略的。
- 一对圆括号()。
- 一对花括号{}。
所以上面两种形式其实是这样的:
- 声明语句: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