1.函数其实是对象,每个函数都是Function类型的实例,一样具有属性和方法,因此,函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。
2.函数的声明:
1 2 3 | function sum(num1,num2){ return num1+num2 } |
或者
1 2 3 | var sum= function (num1,num2){ return num1+num2; }; |
或者
1 | var sum= new Function( "num1" , "num2" , "return num1+num2" ); //不推荐 |
3.JavaScript中函数是没有重载的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | funtion Add(num){ return num + 100; } funtion Add(num){ return num + 200; } var result=Add(100); //300 //将函数名想像成指针,这例子中声明了两个同名函数,后一个就覆盖了前面函数,上述函数相当于 funtion Add(num){ return num + 100; } Add(num){ return num + 200; } var result=Add(100); //300 |
4.函数声明和函数表达式是有区别的,解析器会率先读取函数声明,并使其置于任何代码之前;而函数表达式,则必须等到解析器执行到它所在的代码行,才别执行。
1 2 3 4 | alert(sum(10,10)); //这是正确的,20 function sum(num1,num2){ return num1+num2; } |
1 2 3 4 | alert(sum(10,10)); //这是错误的 var sum= function (num1,num2){ return num1+num2; } |
5.因为JavaScript中的函数名本身就是变量,所以函数也可以当作值来使用。也就是说,不仅可以想传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回。
6.在函数内部,有两个特殊的对象:arguments和this,arguments是一个数组对象,包含传入的所有参数,arguments的主要作用是保存函数参数,但这个对象还有个叫callee的属性,该属性是一个指向拥有这个arguments对象的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //非常经典的递归函数 function factoriak(num){ if (num<=1){ return 1; } else { return num * facaorial(num-1); //与函数名factoriak耦合性太高了 } } //上述代码与函数名耦合性太高,一换函数名就不行了,就可以采用以下方法 function factoriak(num){ if (num<=1){ return 1; } else { return num * arguments.callee(num-1); //这样无论用什么名字都能完成递归调用 } } |
7.this指的是函数执行时所处的作用域。
8.每个函数都包含:length和prototype。length属性表示函数希望接收的参数个数。
1 2 3 4 5 6 7 8 9 10 11 12 | function sayName(name){ alert(name); } function sum(num1,num2){ return num1+num2; } funtion sayHi(){ alert( "hi" ); } alert(sayName.length); //1 alert(sum.length); //2 alert(sayHi().length); //0 |
9.对于JavaScript的引用类型而言,prototype是保存他们实例方法的真正所在。
10.每个函数都包含两个非继承而来的方法:apply()和call();这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
11.apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。其中第二个参数可以是Array的实例,也可以是arguments对象。
1 2 3 4 5 6 7 8 9 10 11 | function sum (num1,num2){ return num1+num2; } function callSum(num1,num2){ return sum.apply( this ,arguments); //传入aguments对象 } function callSum2(num1,num2){ return sum.apply( this ,[num1,num2]); //传入数组 } alert(callSum(10,10)); //20 alert(callSum2(10,10)); //20 |
12.call()方法的第一个参数是作用域没有变化,变化的是其余的参数必须直接传递给函数。
1 2 3 4 5 6 7 | function sum(num1,num2){ return num1+num2; } function callSum(num1,num2){ return sum.call( this ,num1,num2); } alert(callSum(10,10)); |
13.apply()和call()最强大的地方是能够扩充函数赖以运行的作用域。
1 2 3 4 5 6 7 8 9 | window.color= "red" ; var o ={color: "blue" }; function sayColor(){ alert( this .color); } sayColor(); //red sayColor.call( this ); //red sayColor.call(window); //red sayColor.call(o); //blue |
14.每个函数都有一个非标准的caller属性,该属性指向调用当前函数的函数。一般在一个函数内部,铜鼓哟arguments.callee.caller来实现对调用栈的追溯,只做调试用。