函数实际是对象,每个函数都是Function类型的实例,函数名实际上只是指向函数对象的指针,不会与某个函数绑定。
1.定义方式
例如:函数声明:function sum(num1,num2){return num1 + num2;}
例如:函数表达式:var sum = function(num1,num2){return num1+num2};
例如:构造函数:var sum = new Function("num1","num2","return num1 + num2");//不推荐,导致两次解析代码,影响性能。
2.函数是对象,函数名是指针
function sum(num1,num2){
return num1 + num2;
}
alert(sum(10,10)); //20
var anotherSum = sum;//声明变量another,并将其设置为与sum相等。注意:使用不带圆括号的函数名是访问函数指针,而非调用函数。
alert(anotherSum(10,10));//anotherSum和sum都指向了同一个函数,调用并返回结果。
sum = null;
alert(anotherSum(10,10));//20 仍然可以调用
3.没有重载
函数中的参数在内部是用一个数组表示的,函数接收到的始终都是这个数组,不关心数组中有多少个参数与参数类型。可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。
例1
function howManyArgs(){ alert(arguments.length); } howManyArgs();//0 howManyArgs("fdsf");//1 howManyArgs(99,"fsdf");//2
例2
function addSum(){ return arguments[0] + 10; } function addSum(){ return arguments[0] + 20; } alert(addSum(10));//30
后面的函数覆盖了前面的函数定义。
3.函数声明与函数表达式
解析器在向执行环境中加载数据时,会首先读取函数声明,并使其在执行任何代码前可以访问;对于函数表达式,则必须等到解析器执行到它所在的代码行,才会被真正执行。
例如
alert(addSum(10));//20 alert(num(10));//执行错误 function addSum(){ return arguments[0] + 10; } var num = function (){ return arguments[0] + 10; }
4.作为值的函数
函数名本身就是变了,所以函数也可以作为值来使用。也就是说,不仅可以向传递参数一样把一个函数传递给另一个函数,还可以将一个函数作为另一个函数的结果返回。例如
function callSomeFunction(someFuntion,someArgument){ return someFunction(someArgument); }
可以从一个函数中返回另一个函数,这是很有用的技术。例如
function createComparisonFunction(propertyName){ return function(object1,object2){ var value1 = object1[propertyName]; var value2 = object2[propertyName]; if(value1 < value2) return -1; else if(value1 > value2) return 1; else return 0; } } var data = [{name:"nick",age:23},{name:"jason",age:28}]; data.sort(createComparisonFunction("name")); alert(data[0].name);//jason data.sort(createComparisonFunction("age")); alert(data[0].name);//nick
5.函数内部属性
arguments:包含传入函数的所有参数。arguments.callee是一个指针,指向拥有这个arguments对象的函数。可以用于递归执行。从以上例子可知好处。
function factorial(){ if(arguments[0]<1) return 1; else return arguments[0]*arguments.callee(arguments[0]-1); } var trueFactorial = factorial; factorial = function(){ return 0; } alert(factorial(2));//0 alert(trueFactorial(2));//2
6.函数属性和方法
每个函数都有length和prototype。length表示函数希望接受的命名参数的个数。
每个函数都包含两个非继承的方法:apply()和call(),两个方法作用相同。apply(作用域,参数数组),call(作用域,参数列表)。
它们真正强大的地方是扩充函数赖以运行的作用域。例如
window.color = "red"; var o = {color:"blue"}; function sayColor(){ alert(this.color); } sayColor();//red sayColor.call(window);//red sayColor.call(this);//red sayColor.call(o);//blue sayColor.apply(o);//blue
每个函数继承的toLocaleString()和toString()方法始终都返回函数的代码。返回的代码格式因浏览器不同而不同。