JS 之 Function类型

在JS中,函数都是对象,都是Function类型的实例,有自己的属性和方法。因此函数名也像其他引用类型一样,是一个指向函数对象的指针。

定义函数有三种方式:

1、函数声明(有函数声明提升)

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

2、函数表达式(无函数声明提升)

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

3、Function构造函数(不推荐)

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

最后一个参数始终被认为是函数体,前面的所有参数均被认为是参数。该方法会导致两次解析代码:1、常规解析ECMAScript代码 2、解析传入构造函数的字符串,影响性能。

因为函数名仅仅是指向函数对象的指针,所以可以被当成参数或者返回值

例1: 将add作为参数传入op函数

function op(func,arg){
    return func(arg);
}

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

console.log(op(add,20));        //返回30

例2: 从一个函数返回另一个函数

//实现根据对象的某个属性对一个对象数组进行排序

function compare(arg){
    return function(obj1,obj2){
        var val1=obj1[arg];
        var val2=obj2[arg];
        if(val1<val2){return -1;}                //升序
        else if(val1>val2){return -2;}
        else{ return 0; }
    }
}

var objArray=[{name:"master",age:18},{name:"Tom",age:16}];

objArray.sort(compare(age));                    //根据年龄进行比较

console.log(objArray[0].name);                  //输出"Tom"

函数内部属性:

函数内部有两个特殊的对象:arguments this

1、arguments对象是一个类数组对象,里面保存着函数的参数,该对象还有一个callee属性(严格模式下访问该属性会报错),是一个指针,指向拥有该arguments的函数。

比如:一个递归函数,被删掉函数名后......

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

var other=dg;
dg=null;
other(10);                    //报错,因为函数内部调用了dg,可是dg已不存在

//所以,应该将函数内部的dg换为arguments.callee(num-1);

2、this引用的是函数执行的环境对象。

3、caller属性,指向调用当前函数的函数的引用

function outer(){
    inner();
}

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

outer();        //alert 弹出 outer的源代码

inner.caller == arguments.callee.caller;

函数属性和方法:

1、length 表示函数期望接受的命名参数的个数。

2、prototype 属性 是不可枚举属性,用for-in无法发现。

3、apply( ) 和 call( ) 这两个是非继承而来的函数。在特定的作用域中调用函数,实际上是设置函数体内this对象的值。

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

function op(num1,num2){
    return sum.apply(this,arguments);
}

op(10,20);                //返回30

sum.apply 修改了sum函数体内的this对象的值。call用法类似,只是call需要一个一个传参,apply要传一个参数数组。

这两个函数真正强大的地方是“扩充函数赖以运行的作用域”

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

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

sayColor.call(this);       //显示red

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

sayColor.call(o);          //显示blue,在这里sayColor的函数作用域就被调到了o对象中。

使用call和apply来扩充作用域的好处就是对象不需要与任何方法有任何的耦合关系。

4、bind( ) 方法,该方法会创建一个 调用它的函数 的实例,其this值指向参入的参数。

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

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

var other=sayColor.bind(o);

other();            // blue

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值