JavaScript引用类型——Function

    在ECMAScript中,函数是对象,每个函数都是Function类型的实例,而且与其他引用类型一样具有属性和方法。函数名实际上是一个指向函数对象的指针,不会与函数绑定。函数可以如下面的语法定义:

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

    也可以像下面一样定义:

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

    还可以使用Function构造函数。Function构造函数可以接收任意数量的参数,最后一个参数始终被看做函数体,前面的参数被看做是新函数的参数。

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

    这种方式会导致解析两次代码(第一次是解析常规ECMAScript代码,第二次是解析传入构造函数中的字符串),从而影响性能。

1、函数没有重载

    在ECMAScript中没有函数重载。因为函数名是作为指针的概念存在的,重复声明同一个函数名相当于覆盖指针引用,所有同一个函数名同时只能保存一个函数引用。

function fn(num1){
    return num1;
}

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

console.log(fn(1));//NaN

    上面的代码以下面相同:

var fn = function(num1){
    return num1;
}

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

console.log(fn(1));//NaN
2、函数声明与函数表达式的区别

    函数声明与函数表达式的语法功能相同,但是其解析的过程却是不同的。解析器会先读取函数声明,并使其在任何执行代码前,就是说解析器会先扫描脚本,然后将声明的函数置于脚本顶部,以便于接下来执行的可以调用函数。这样就可以解释为是声明的函数可以在声明之前调用。

console.log(sum(1,2));//3
function sum(num1,num2){
    return num1 + num2;
}

    而对于函数表达式,解析器则会当作普通的赋值操作,而不会对其进行特殊的解析。下面代码会抛异常。

console.log(sum(1,2));//unexpected identifier
var sum = function(num1,num2){
    return num1 + num2;
}
3、函数内部属性

    函数内部有两个特殊的对象:arguments和this。arguments是一个数组对象,包含传入函数的所有参数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(){
    console.log(this.color);
}

sayColor();//"red"

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

    还有另外一个属性:caller。保存调用当前函数的引用,如果在全局作用域中调用,值为null。

function outer(){
    inner();
}

function inner(){
    console.log(arguments.callee.caller);
}

outer();
4、函数属性和方法

    ECMAScript中的函数是对象,也有属性和方法。每个函数都有两个属性:length和prototype。其中,length属性表示函数要接收的命名函数的个数。

function sayName(name){
    console.log(name);
}

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

function sayHi(){
    console.log("hi");
}

console.log(sayName.length);//1
console.log(sum.length);//2
console.log(sayHi.length);//0

    每个函数包含两个非继承而来的方法:apply()和call()。apply()方法接收两个参数:一个是在其中运行函数的作用越,另一个是参数数组。第二参数可以是Array实例,也可以是arguments对象。

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]);//传入数组
}

console.log(callSum1(10,10));//20
console.log(callSum2(10,10));//20

    对于call(),第一个参数this没有变化,但是其他参数需要直接传递函数。

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

function callSum(num1, num2){
    return sum.call(this, num1,num2);//传入数组
}

console.log(callSum(10,10));//20

    apply()和call()能够扩充函数运行的作用域。

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

function sayColor(){
    console.log(this.color);
}

sayColor();//red

sayColor.call(this);//red
sayColor.call(window);//red
sayColor.call(o);//blue

    ECMAScript 5定义了一个方法:bind()。

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

function sayColor(){
    console.log(this.color);
}

var objectSayColor = sayColor.bind(o);
objectSayColor();//blue

    支持bind()方法的浏览器有IE9+、FF4+、Safari5.1+、Opera 12+和Chrome。

转载于:https://my.oschina.net/u/1457082/blog/472265

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值