JavaScript 中apply()、call()和bind()方法的使用

apply()和call()

我们可以将call()和apply()看做是某个对象的方法,通过调用此方法来简介调用函数。
call()和apply()两个方法实际上差别不大,只是在方法的第二个参数类别上有区别,call()第二个参数为一系列参数,而apply()第二个参数为一个数组,即如下所示。

f.call(obj,1,2,...);
f.apply(obj,[1,2,...]);

这是这两个方法的参数区别,他们第一个参数调用上下文实参,估计很多朋友都不理解上下文实参是个啥,其实这也是我看的书上这么说的,我的理解就是传入一个对象,这个对象决定了此方法使用时候的上下文。
下面介绍几个例子来说明:

    function Person(name, age) {
        this.name = name;
        this.age = age;
   }
    Person.prototype.showName = function() {
        console.log('Person showName -' + this.name);
    };
    Person.prototype.setName = function(name) {
        this.name = name;
        console.log('setName-' + name);
    };
    Person.prototype.showAge = function() {
        console.log('Person showAge - ' + this.age)
    };

    function Women(name,age) {
        Person.call(this,[name,age]);//this Women对象调用Person中所有方法
        this.sex = 'male';
    }
    Women.prototype = Person.prototype;
    Women.prototype.showSex = function() {
        console.log('Women showSex-' + this.sex)
    };
    Women.prototype.showName = function() {
        console.log('Women showName - ' + this.name);
    };

    var women = new Women('cyl', 22);
    women.showName();
    women.showSex();
    women.setName('sf');//此处更改this.name调用了Person.setName()的方法
    women.showName();
    //Women showName - cyl,22
    //Women showSex-male
    //setName-aaa
    //Women showName - sf
//将对象o中名为m()的方法替换为另一个方法
//可以在调用原始的方法之前和之后记录日志消息
function trace(o, m){
    var original = 0[m];      //在闭包中保存原始方法
    o[m] = function(){       //定义新的方法
        console.log(new Date(), "Entering:", m);//输出日志信息
        var result = original.apply(this, arguments);//调用原始函数
        console.log(new Date(), "Exiting:", m);
        return result;
    };
}

trance()函数接收两个参数,一个对象和一个方法名,它将指定的方法替换为一个新方法,这个新方法是“包裹”原始方法的另一个泛函数。这种动态修改已有方法的做法有时候也成为“monkey-patching”。

bind()方法
这个方法的主要作用就是将函数绑定到某个对象上,一个函数调用bind()方法将返回一个新的函数。举个例子吧:

function f(y){return this.x + y;}   //这个是待绑定的函数
var o = {x: 1};             //将要绑定的对象
var g = f.bind(o);          //通过调用g(x) 来调用 o.f(x)
g(2);   // => 3

可以通过如下代码轻易实现这种绑定:

//返回一个函数,通过调用它来调用o中的方法f()
//传递它所有实参
function bind(f, o){
    if(f.bind) return f.bind(o);//如果bind方法存在的话使用bind方法
    else return function(){
        return f.apply(o,arguments);
    }
}

当然bind()方法不仅仅是将函数绑定值一个对象,它还附带一些其他的应用:除了第一个实参之外,传入bind()的实参也会绑定值this,之歌附带的应用是一种常见的函数式编程技术,有时也被成为“柯里化(currying)”。参考下面的例子中的方法的实现:

    var sum = function(x, y) {
        //返回两个实参的和值
        return x+y;
    }
    //创建一个类似sum的新函数,但是this的值绑定到null
    //并且第一个参数绑定到1, 这个心的函数期望只传入一个实参
    var succ = sum.bind(null, 1);
    succ(2)    //  =>3     x 绑定到 1, 传入2作为实参

    function f(y, z) {
        return this.x + y+ z;
    }
    var g = f.bind({x:1},2);
    g(3) //  =>6     this.x 绑定到{x:1}.x =1   y绑定到2, z传入3作为实参
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值