JavaScript引用类型-函数

Function类型是ECMAScript引用类型中的一种,它就是我们熟悉的函数。有意思的是,在ECMAScript中,函数实际上是对象。

每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。

由于函数是对象,因此函数名实际上就是指向这个函数对象的指针,不会与某个函数绑定。

定义函数的三种方式:

1.使用函数声明语法。

function sum(num1,num2){
    return num1+num2;
}

2.使用函数表达式定义。
var sum = function(num1,num2){
     return num1+num2;
};
通过变量名称sum即可引用这个函数,sum();

因为是使用表达式定义,所以别忘了表达式要以;结尾。


3.使用Function构造函数。Function构造函数接收任意数量的参数,并且把最后一个参数看成函数体。

但这种方式性能不好,已不推荐使用。

var sum = new Function("num1","num2","return num1+num2");

我们需要注意的是,函数名仅仅是指向这个函数对象的一个指针,也就是一个变量而已,一个函数可能会有多个名字,就像一个对象可以被多个指针引用一样。

例如上面的sum变量,当我们要调用函数时,用函数加上圆括号,sum(1,2);。而不带括号的函数名sum表示的是我们访问这个函数指针,而不是调用函数。在当把函数作为值传递时要注意这点。


理解了函数名只是一个指针,那也就可以理解为什么ECMAScript中没有函数重载了,当我们写了两个同名的函数时,只不过是把这个函数名代表的指针指向了后写的那个函数对象,执行的结果看上去就是前一个函数被后一个同名的函数替代了。


之前说到定义函数的两种方式,函数声明和函数表达式。它们在定义函数时作用是一样的,但是在解析器在向执行环境(比如浏览器)加载我们的js代码时,对这两种函数定义的加载顺序是不一样的。

解析器会先读取函数声明,并使其在执行任何代码前可以被访问;至于函数表达式,则只有等到解析器执行到它所在的那行代码时,才会被解释然后执行。例如:

alert(sum(1,2));  //可以执行

//虽然函数声明写在函数调用的后面
function sum(num1,num2){
    return num1+num2;
}

但下面这样就不行:
alert(sum(1,2));  //产生错误

//函数表达式
var sum = function(num1,num2){
     return num1+num2;
};

由于在ECMAScript中,函数名本身就是变量,所以函数也可以当做值来使用。也就是说,不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回。

function callFunction(function,argument){
     return function(argument);
}

function add(num){
    return num + 100;
}

var result = callFunction(add,100);

 alert(result);  //200

在函数的内部,有两个特殊的对象:arguments和this。

arguments对象与数组类似,里面包含着传入函数中的所有参数,可以使用数组的方括号语法来访问。ECMAScript函数不介意传递进来多少参数,也不在乎传递进来参数的类型,你可以定义一个接收两个参数的函数,但使用时可以传递任意个参数,或者一个也不传。因为对于ECMAScript函数来说,命名的参数只不过是为我们在函数体使用参数时提供了便利,它并不是必须的,在函数体内可以使用arguments对象来得到传递给函数的每一个参数。

此外,arguments对象还有一个callee属性,该属性是一个指针,指向拥有这个arguments对象的函数。


函数的另一个特殊对象是this,这个this的行为和Java中的this类型。this引用的是函数据以执行的环境对象。(当在全局作用域中调用某个函数时,this对象引用的就是window这个全局对象)。

window.color = "red";
var o = {color : "yellow"};

function sayColor(){
    alert(this.color);
}

sayColor();  //red

o.sayColor = sayColor;
o.sayColor();  //yellow
在sayColor函数调用之前,this的值并不确定。在全局环境中调用sayColor(),this的值就是window。当调用o.sayColor()时,this引用的就是对象o。


函数的属性:length和prototype。

length属性比较简单,它表示函数希望接收的命名参数的个数,就是定义函数时定义的参数的个数。

prototype属性,就是函数对象得到原型属性,这个在介绍对象的时候介绍过。这里不再展开。


函数的方法:

每个函数都包含两个非继承而来的方法:apply()和call()。

这两个方法的用途都是在特定的作用域中调用函数,实际上也就是用来设置函数体内this对象值。

这两个方法的区别仅仅在于接收参数的方式不同,当不给函数传递参数的时候,使用哪个方法都无所谓。

window.color = "red";
var o = {color : "yellow"};

function sayColor(){
    alert(this.color);
}
sayColor.apply(o);  //yellow
sayColor.call(o);  //yellow

sayColor();  //red
sayColor.call(window);  //red


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。