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对象,其行为与JavaC#中的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;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值