欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript学习记录-Function类型

程序员文章站 2024-03-18 21:20:46
...

在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;

相关标签: JavaScript