相关知识点:
arguments和this。
arguments.callee和arguments.callee.caller
length和prototype
apply( )和call( )
bind( )
1.Function类型
函数实际是对象,也具有属性和方法,函数名实际是一个指向函数对象的指针
注意:使用不带括号的函数名是访问函数指针,不是调用函数。
(1)定义
//1 使用“函数声明”定义
function sum (num1, num2){
return num1+num2;
}
//2 使用“函数表达式”定义
var sum=function(num1,num2){
return num1+num2;
};//注意这里加";"号,通过变量sum就能引用函数
(2)没有重载
创建两个同名函数,后面的会覆盖前面的。
(3)函数声明和函数表达式
//函数声明定义
alert(sum(10,10));
function sum (num1, num2){
return num1+num2;
}
能正常运行,使用函数声明进行定义,即使函数声明在函数调用之后,JavaScript解析的时候也会把声明提升到顶部,所以没有错误。
//函数表达式定义
alert(sum(10,10));
var sum=function(num1,num2){
return num1+num2;
产生错误。因为使用函数表达式必须到它所在的代码行才被解析,所以在定义前调用就报错unexpected identifier。
除此之外它们是等价的
(4)函数内部属性
在函数内部,有两个特殊的对象:arguments和this。
arguments: ECMAScript函数不介意传入几个参数,什么类型的参数。也就是说虽然你只是定义函数只接受2个参数,但你可以给它传入1个或3个参数甚至不传。
函数的参数在内部用一个数组来表示!!!这个数组才不管你有几个,是什么样类型的,自己看着办。
可以通过arguments对象来访问这个数组,从而获得传递给函数的每个参数。
arguments对象只是和数组类似,但它不是Array的实例哦。
可以用方括号语法访问它的每个元素:arguments[0],arguments[1]
可用length属性来确定传入参数个数:arguments.lengththis:引用的是函数执行的环境对象(当在全局作用域调用函数时,this对象引用的是window对象)
window.color="red";
var o={color:"blue"};
function colors(){
alert(this.color);
}
colors();//"red" this->window
o.colors=colors;
o.colors();//"blue" this->o
- arguments.callee
callee:指向拥有这个arguments对象的函数。
function factorial(num){
if(num<=1){
return 1;
}
else{
return num*factorial(num-1);
}
}
//使用arguments.callee
function factorial(num){
if(num<=1){
return 1;
}
else{
return num*arguments.callee(num-1);//不需考虑函数名的修改
}
}
- arguments.callee.caller
caller :保存着调用当前函数的函数的引用
function outer(){
inner();
}
function inner(){
//alert (inner.caller);
alert (arguments.callee.caller);
}
outer();
//结果会在警告框中显示outer()函数的源代码。outer()调用了inner(),所以Inner.caller()指向outer();
(5)函数属性和方法
- 每个函数都有两个属性:length和prototype
length: 表示函数希望接收的命名参数的个数
prototype: 引用类型的所有实例方法的正在所在。换句话说,toString( )等方法实际保存在prototype的名下。
function sum(num1,num2){
return num1+num2;
}
alert(sum.length);//2
- 每个函数都包含两个非继承而来的方法:apply( )和call( )
这两方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
//apply()接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组
function sum(num1, num2){
return num1+num2;
}
//传入this作为this值,因为在全局作用域中调用,所以传入的是window
function sum1(num1, num2){
return sum.apply(this, arguments);//传入arguments
}
function sum2(num1, num2){
return sum.apply(this, [num1,num2]);//穿入数组
}
alert(sum1(10,10));//20
alert(sum2(10,10));//20
function sum(num1, num2){
return num1+num2;
}
//传入this作为this值,因为在全局作用域中调用,所以传入的是window
function sum1(num1, num2){
return sum.call(this, num1, num2);//区别!!!传入的参数逐个列出
}
它们两个的用武之地,扩充函数赖以生存的作用域
window.color="red";
var o={color:"blue"};
function colors(){
alert(this.color);
}
colors();//red
colors.call(this);//red
colors.call(window);//red
colors.call(o);//blue
ECMAScript还定义了一个方法bind( ),这个方法会创建一个函数实例,其this值会被绑定到传给bind()函数的值。
window.color="red";
var o={color:"blue"};
function colors(){
alert(this.color);
}
var objectcolors=colors.bind(o);//函数colors的this和o绑定
objectcolors();//blue