JavaScript学习记录-Function类型
在ECMAScript中,Function(函数)类型实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名 实际上也是一个指向函数对象的指针。
1、函数的声明
(1) 普通的函数声明
function test(num1,num2){
return num1+num2;
}
(2) 使用变量初始化函数
var test = function(num1,num2){
return num1+num2;
};
2、作为值的函数
ECMAScript中函数名本身就是变量,所以函数也可以作为值来使用。换言之,可以像传递参数一样将一个函数传递给另一个函数,也可以将一个函数作为另一个函数的结果返回。
function test(sumFunction,num){
return sumFunction(num);
}
function sum(num){
return num+10;
}
var result = test(sum,10);
alert(result);
对上例做一个详解:函数test里面有两个参数sum和10,也就是第一条语句中sumFunction为sum,num为10,返回的结果sunFunction(10),这个也就是第二个函数,返回结果10+10=20。
3、函数内部属性
在函数内部,有两个特殊的对象:(1) arguments,(2) this。
(1)arguments是一个类数组对象,包含着传入函数中的所有参数,主要用途是保存函数参数。arguments这个对象还有一个属性callee,这个属性是一个指针,指向拥有arguments对象的函数。
function test(num){
if(num <= 1){
return 1;
}
else{
return num*test(num-1);
}
}
alert(test(5)); //返回结果120
对于阶乘函数一般要用到递归算法,所以函数内部一定会调用自身。如果函数名不改变是没有问题的,但一旦改变函数名,内部的自身调用需要逐一修改,这在后期维护过程中就显得非常繁琐。为了解决这个问题,我们可以使用arguments.callee来代替。
function test(num){
if(num<=1){
return 1;
}
else{
return num*arguments.callee(num-1);//arguments.callee指向这个函数
}
}
alert(test(5));
(2)this对象,其行为与Java和C#中的this大致相似。换言之,this引用的是函数用以执行操作的对象,或者说函数调用语句所处的那个作用域。note:当在全局作用域中调用函数时,this对象引用的就是window。
window.color = "红色"; //全局的color
alert(this.color); //打印全局的color,这里的this就是window
var test ={
color:"蓝色", //这里的color是test下的属性,也就是局部变量
sayColor:function(){
alert(this.color); //此时的this只能在test里的color
}
};
test.sayColor(); //打印局部的color
alert(this.color); //
4、函数属性和方法
ECMAScript中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性:length和prototype。其中,length属性表示函数希望接受的命名参数的个数。
function test(name,age){
alert(name+age);
}
alert(test.length);
prototype属性,是保存所有实例方法的真正所在,也就是原型。prototype下有两个方法:apply()和call(),每个函数都包含这两个非继承而来的方法。这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
function test(num1,num2){
return num1+num2; //原函数
}
function sayTest1(num1,num2){
return test.apply(this,[num1,num2]);//this表示作用域,此处是window,[]中test所需要的参数
}
function sayTest2(num1,num2){
return test.apply(this,arguments);//arguments对象表示test所需要的参数
}
alert(sayTest1(10,10)); //输出结果20
alert(sayTest2(10,10)); //输出结果20
call()方法与apply()方法相同,其区别仅仅在于接收参数的方式不同。对于call()方法而言,第一个参数是作用域,没有变化,变化只是其余的参数都是直接传递给函数的。
function test(num1, num2) {
return num1 + num2;
}
function sayTest(num1, num2) {
return test.call(this, num1, num2); //和apply区别在于后面的传参
}
alert(sayTest(10,10)); //输出结果20
事实上,apply()方法和call()方法并不只用于传递参数,他们经常使用的地方是能够扩展函数依赖以运行的作用域。
var color = '红色'; //全局
var test = {
color : '蓝色' //局部
};
function sayColor() {
alert(this.color);
}
sayColor(); //作用域在window,红色
//用call来实现对象冒充,改变作用域
sayColor.call(this); //作用域在window,红色
sayColor.call(window); //作用域在window,红色
sayColor.call(test); //作用域在test对象里面,蓝色
使用call()或者apply()来扩充作用域的最大好处,就是对象不需要与方法发生任何耦合关系(耦合,就是互相关联的意思,扩展和维护会发生连锁反应)。换言之,test对象和sayColor()方法之间不会有多余的关联操作,譬如test.sayColor = sayColor;
推荐阅读
-
JavaScript学习记录-Function类型
-
(JavaScript学习记录):jQuery 尺寸、位置操作
-
CG学习记录(一)数据类型
-
JavaScript学习笔记(四)【数据类型】
-
【JavaScript学习笔记】6:数据类型,object类型及其判定,常用类型转换
-
oracle中修改有数据的表的字段类型 博客分类: Oracle学习记录自学记录 oracle表格式的重新定义
-
javascript学习笔记——事件流、事件处理程序、事件对象、事件类型、内存和性能
-
js中判断Object、Array、Function等引用类型对象是否相等_javascript技巧
-
Javascript学习笔记一 之 数据类型_基础知识
-
Javascript入门学习第二篇 js类型_基础知识