Javascript引用类型之Function类型

本文详细介绍了JavaScript中函数的定义方式、函数作为对象的特点、函数的属性和方法等内容,并对比了函数声明与函数表达式的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

一、定义函数有三种方法:

1、函数声明

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

2、函数表达式

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

以上方法定义了一个sum变量并将其初始化为一个函数。函数末尾有一个分号,这和声明其他变量一样。
3.Function构造函数

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

不推荐使用这种定义方法,因为这种语法会导致两次解析代码(第一次解析常规ECMAScript代码,第二次是解析传入构造函数中的字符串),从而影响性能。

函数名仅仅是指向函数的指针,因此一个函数可能会有多个名字。如下:

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

alert(sum(10,10));      //20

var anotherSum = sum;
alert(anotherSum(10,10));   //20        

二、函数没有重载

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

function addSum(num){
    return num+200;
}

var result = addSum(100);   //300;

后面的函数会覆盖前面的函数。

三、函数声明与函数表达式的区别

在执行JS时,解析器会先读取函数声明,并使其在执行任何代码之前可用(可以访问);而对于函数表达式,则必须等到解析器执行到它所在的代码行,才能真正被解释执行。如下:

alert(sum(10,10));  //20
function sum(num1,num2){
    return num1+num2;
}

上面的代码是可以正常执行的。
但是如果是函数表达式的话,则会报错。

alert(sum(10,10));  //unexpected identifier
var sum = function(num1,num2){
    return num1+num2;
};

四、函数作为参数传入另一个函数
因为函数名本身就是变量,所以函数也可以作为值来使用。

function callSomeFunction(someFunction, someArgument){
    return someFunction(someArgument);
}

这个函数接收两个参数,第一个参数是一个函数,第二个参数是要传递给这个函数的值。

五、函数的属性和方法
在函数内部,有两个特殊对象,arguments和this。arguments的主要用途是保存函数参数,但这个对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。

function factorial(num){
    if(num<=1){
        return 1;
    }else{
        return num*factorial(num-1);
    }
}

function factorial(num){
    if(num<=1){
        return 1;
    }else{
        return num*arguments.callee(num-1);
    }
}

第二种方法保证了引用函数时不受函数名的干扰。

接下来看看this的使用。

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

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

sayColor();     //"red";

o.sayColor = sayColor();
o.sayColor();   //"blue"

因为sayColor()是在全局作用域中定义的,当在全局作用域中调用sayColor()时,this引用的是全局对象window;而把这个函数赋给对象o并调用o.sayColor()时,this引用的是对象o。

ECMAScript5还规范了另一个函数对象的属性:caller。来看下面的例子:

function outer(){
    inner();
}

function inner(){
    alert(inner.caller);
}
outer();

以上代码会alert出outer()函数的源码。因为outer()调用了inner(),所以inner.caller就指向outer。也可以通过arguments.callee.caller来访问相同的信息。
需要注意的是:不能为函数的caller属性赋值,否则会导致错误。

五、函数的属性和方法

1.length:返回函数接收命名参数的个数。

function sayName(name){
    alert(name);
}

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

function sayHi(){
    alert("Hi");
}

sayName.length; //1
sum.length;     //2
sayHi.length;   //0

2.property属性
对于引用类型来说,property是保存它们所有实例方法的真正所在。也就是说,诸如toString()和valueOf()等方法实际上都保存在propertytype名下,只不过通过各自对象的实例访问罢了。

每个函数都有两个非继承而来的方法:apply()和call()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内的this对象的值。

apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。

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

function callSum1(num1, num2){
    return sum.apply(this, arguments);  //传入arguments对象
}

function callSum2(num1, num2){
    return sum.apply(this, [num1, num2]);  //传入数组
}

alert(callSum1(10,10));     //20
alert(callSum2(10,10));     //20

call()与apply()方法的作用相同,区别在于接收参数的方式不同。对于call()方法而言,必须把传递给函数的参数列举出来。

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

function callSum(num1, num2){
    return sum.call(this, num1, num2);
}

alert(callSum(10, 10));

实际上,apply()和call()真正强大的地方在于能够扩充函数赖以运行的作用域。

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

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

sayColor();     //red

sayColor.call(this);    //red
sayColor.call(window);  //red
sayColor.call(o);       //blue
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值