apply call bind的用法与实现

概念

本文来源:http://www.248tyc.com/blog_csdn_net/

申博太阳城现金网游戏,  这一争议时刻发生在比赛第三节福建队的一次进攻中,在内线卡位试图争抢篮板的两人纠缠在了一起,最终发生了冲突的一幕。  “你都懂这些法律程序,但是,我们目前的特点是‘和谐执行’。  市场人士指出,公积金市场化运作要有一个前提,那就是确保刚需购房的公积金需求  在相关部门的共同推动下,养老基金的入市脚步渐进,接下来,住房公积金什么时候能市场化运作又成为大家关注的焦点。  在中消协专家顾问邱宝昌看来,由于IC卡成本下降等原因,出台于2001年的上述办法已经不适应当前形势,收取押金缺乏充足理由。

据了解,韩国市场是奥迪和宾利等品牌增长最快的市场之一。此弹从60年代末开始装备我军后成为了国内乃至全世界数量最大、装备最广的一种手榴弹。权利人、利害关系人申请查询、复制不动产登记资料应当提交下列材料:1、查询申请书(说明查询目的、利害关系);2、申请人的身份证明材料。视频简介近几年随着SUV市场的不断火爆,自主的车型越来越受到消费者的青睐。

  ·11月11日,网络上疯传一张上汽与奥迪签约的图片,显示上汽集团与大众汽车集团在德国狼堡签署谅解备忘录。  一个事实是,中国本土企业起步晚、底子薄,通过引进与合资,确实在较短时间里提升了技术水平,缩短了与世界的差距,满足了市场需求。601所总体设计初期,选择的发动机是预研的国产中推涡扇发动机两台(加力推力8120KG)或俄罗斯的RL33发动机(加力推力8250KG),在飞行升限、最大飞行速度、爬升率、稳定盘旋过载、基本航程和起降性能等参数,经过总体综合优化设计,得出高机动隐身战斗机的翼载应为325350KG/m2,推重比应选在1.10~1.15之间,飞机的总重限制在15吨。  新浪体育讯  北京时间12月7日,第21届三星车险杯世界围棋大师赛三番棋决赛第2局在韩国战罢。

apply call 和bind 允许为不同的对象分配和调用属于一个对象的函数/方法。同时它们可以改变函数内 this 的指向。

区别

  • apply 和 call 接收的参数形式不同

  • apply 和 call 都是直接调用函数并得到函数执行结果,而 bind 会返回待执行函数,需要再次调用

用法演示

我们先创建一个对象 parent

const parent = {
    name: 'parent',
    sayPerson (age, addr) {
        return {
            name: this.name,
            age,
            addr
        }
    }
}

显然它具有 name 属性,及方法 sayPerson,我们现在可以通过 parent.sayPerson() 来输出该对象信息。

const person = parent.sayPerson(60, 'shenzhen');
/{name: "parent", age: 60, addr: "shenzhen"}

现在我们再创建一个对象 son

const son = {
    name: 'son'
}

我们现在也想得到 son 的信息,但是 son 对象没有 sayPerson 函数怎么办?借助已有的 parent 对象和 call 方法,我们可以这样写

const person = parent.sayPerson.call(son, 26, 'shenzhen');
/{name: "son", age: 26, addr: "shenzhen"}

可以看出,通过调用 call 函数,我们为 son 对象分配了 sayPerson 方法并进行调用。实现了一个对象可以调用不属于它自己的方法,并且函数内的 this 指向该对象。apply 方法的用法其实一样,只是传参有些区别

const person = parent.sayPerson.call(son, [26, 'shenzhen']);
/{name: "son", age: 26, addr: "shenzhen"}

bind 函数则不直接调用函数,而是返回待调用函数

const sayPersonFn = parent.sayPerson.bind(son, 26, 'shenzhen');

const person = sayPersonFn();
/{name: "son", age: 26, addr: "shenzhen"}

以上就是三者的使用方法和区别,下面我们来看看它们是如何实现的

实现

call的实现

实现原理就是为对象 obj 添加需要调用的方法,接着调用该方法(此时 this 指向 obj),调用过后再删除该方法

简单版

Object.prototype.callFn = function (...args) {
    /第一个参数为目标对象
    const context = args[0];

    args.shift();

    /为对象赋值需要调用的方法
    context.fn = this;

    /调用该方法
    context.fn(...args);

    /删除方法
    delete context.fn;
}

加上返回值

Object.prototype.callFn = function (...args) {
    /第一个参数为目标对象
    const context = args[0];

    args.shift();

    /为对象赋值需要调用的方法
    context.fn = this;

    /调用该方法
    const result = context.fn(...args);

    /删除方法
    delete context.fn;

    return result;
}

在测试中发现,我们调用 call,如果第一个参数是 null 或者 undefined,那么 call 将以全局 window 来调用方法,此时 this 也指向 window。如果第一个参数不是对象类型,则以空对象 {} 来调用方法。

Object.prototype.callFn = function (...args) {
    /第一个参数为目标对象
    let context = args[0];

    /undefined 和 null 指向 window
    if (context === null || context === undefined) {
        context = window;
    }

    /不是对象类型则创建空对象
    if (typeof context !== 'object') {
        context = {};
    }

    args.shift();

    /为对象赋值需要调用的方法
    context.fn = this;

    /调用该方法
    const result = context.fn(...args);

    /删除方法
    delete context.fn;
    
    return result;
}

至此,我们实现了一个完整的 call 方法。

apply的实现

既然和 call 只存在传参的区别,那我们只需要简单修改下已实现的 call 方法即可。

Object.prototype.applyFn = function (...args) {
    let context = args[0];

    if (context === null || context === undefined) {
        context = window;
    }

    if (typeof context !== 'object') {
        context = {};
    }

    args.shift();

    context.fn = this;

    /和 call 存在差异的地方
    const result = context.fn(...args[0]);

    delete context.fn;

    return result;
}

bind的实现

在实现了 apply 和 call 的前提下,bind 的实现也比较简单。

Object.prototype.bindFn = function (...args) {
    /实际就是多包了层待执行函数
    return () => {
        return this.applyFn(args[0], (args || []).slice(1));
    }
}

至于以 bind 方法返回的函数作为构造函数来创建对象会存在的问题请参考申博太阳城现金网游戏JavaScript深入之bind的模拟实现

总结

call apply bind 在工作中实际上是比较常见的函数,特别是在一些框架或库的源码中,但是经常有人会混淆它们的用法。希望大家通过此篇文章可以彻底弄清它们的作用与区别,并且知道其实现原理,知其然知其所以然。

参考


欢迎到前端学习打卡群一起学习~516913974

posted @ 2020-05-11 23:18  申博太阳城现金网游戏沐晓  阅读(...)  评论(...编辑  收藏
申博在线直营网 菲律宾太阳网城上娱乐 申博手机版下载登入 菲律宾申博电子游戏登入 菲律宾娱乐在线网直营 申博登录不了
申博在线娱乐登入网址 申博太阳城登入 太阳成娱乐成总代理 申博游戏手机版 申博电子游戏 菲律宾申博游戏登入
申博网络游戏直营网 菲律宾申博开户直营网 申博太阳城直营网 申博现金充值登入 www.sun8066.com 申博游戏网直营网