在ECMAScript中,Function(函数)类型是对象。每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。因为函数是对象,所以函数名实际上也是一个指向函数对象的指针;
一.函数有三种声明的方式:
1.普通的声明
2.使用变量初始化函数
3.使用Function构造函数; 因为function是对象所以可以使用New来构造,但是这样的语法会导致解析两次代码,影响心梗,所以不推荐使用;
二.作为值的函数
ECMAScript中的函数名本身就是变量,所以可以作为值来使用。
1.可以像传递参数一样把一个函数传递给另一个函数,
2.可以将一个函数作为另一个函数的结果返回;(下面例子说明)
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;"> function box(someFunction,num)
{
return someFunction(num); //someFunction
}
function sum(num)
{
return num+10;
}
var result = box(sum,10); //传递函数到另一个函数里;sum函数作为参数,传递到box函数中。
alert(result);</span></span>
三.函数内部属性;
在函数内部,两个特殊对象:arguments 和 this 。
arguments对象;
arguments:一个类数组对象,包含传入函数中的所有参数,用途是保存函数参数;(apply和call的例子中体现)
arguments对象有一个callee的属性,该属性是一个指针,指向拥有该arguments对象的函数;
在使用递归算法时,函数内部会调用自身,那么函数内部就会用到函数的名字,一旦函数名字发生变化则内部函数名也需要进行修改,但是如果在函数内部,能够用一个对象标识自身,那么就不会随着函数名字的变化而变化。
arguments.callee代替函数名称来解决这个问题;
<span style="font-family:SimSun;"> function box(num)
{
if(num<=1)
{
return 1;
}
else
{
return arguments.callee(num-1); //此处的arguments.callee代表box这个函数名称,
//但是当box函数名称变化的时候,这里不用变化,仍然表示该函数;
}
}</span>
this对象:
引用的是函数据以执行操作的对象,或者函数调用语句所处的作用域;在全局作用域中调用函数时,this对象引用window。
<span style="font-family:SimSun;font-size:18px;"> window.color = '红色的'; //color是全局的,所用this 对象引用的是window;
alert(this.color);
var box = {
color:'蓝色的', //局部的color;
sayColor:function(){
alert(this.color); //此时的this指box里的color;
//sayColor这个函数是box对象的函数;this引用的是函数据以执行操作的对象box;
}
};
box.sayColor(); //蓝色的;
alert(this.color); //此处this,依然是window所以是红色的;</span>
四.函数属性和方法
ECMAScript中函数时对象,所有有属性和方法。每个函数都包含两个属性;length 和 prototype。
length:函数希望接收的命名参数的个数;
prototype:它是保存所有实例方法的真正所在, 即原型;这个属性是一个对象,包含可以有特定类型的所有实例共享的属性和方法;prototype是一个对象,它有两个方法apply() 和 call(),每个函数都有这两个非继承而来的方法;
apply()和call()都在特定的作用域中调用函数,实际上是设置函数体内this对象的值;
<span style="font-family:SimSun;font-size:18px;"> function box(num1, num2) {
return num1 + num2; //原函数
}
function sayBox(num1, num2) {
return box.apply(this, [num1, num2]); //this 表示作用域,这里是 window 第一个参数是作用域;
} //[]表示 box 所需要的参数
function sayBox2(num1, num2) {
return box.apply(this, arguments); //arguments 对象表示 box 所需要的参数
}
alert(sayBox(10,10)); //20
alert(sayBox2(10,10)); //20</span>
call()和apply()相同,区别只是接收参数的方式不同;第一个参数是作用域,其它的参数都是直接给函数;
apply() 和 call()最常使用的是能够扩展函数运行的作用域;
<span style="font-family:SimSun;font-size:18px;"> var color = '红色的'
var box = {
color:'蓝色的'
}
function sayColor()
{
alert(this.color);
}
sayColor(); //作用域在window;
sayColor.call(this) //作用域在window;
sayColor.apply(this) //作用域在window;
sayColor.call(box) //作用域在box;
sayColor.apply(box) //作用域在box;</span>
apply() 和 call()来扩充作用域的最大的好处,是对象不需要与方法发生任何耦合关系;
总结:
学习是一个重复的过程,反复的运用,不断的总结,第一次不理解没关系,再学习一遍,跟同行交流一下,在实践中运用,这样的成长会更加深刻。