【前端精进之路】JS篇:第9期 深度解析call,apply,bind

写在前面

这里是小飞侠Pan🥳,立志成为一名优秀的前端程序媛!!!

本篇文章收录于我的专栏:前端精进之路

同时收录于我的github前端笔记仓库中,持续更新中,欢迎star~

👉https://github.com/mengqiuleo/myNote


call,apply,bind 这三个函数是 Function原型上的方法 Function.prototype.call()Function.prototype.applyFunction.prototype.bind(),所有的函数都是 Funciton 的实例,因此所有的函数可以调用call,apply,bind 这三个方法。

call 与 apply

第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefinednull,则默认指向全局window

如果你使用的时候不关心 this是谁的话,可以直接设置为 null

都可以传参,但是apply是数组,而call是参数列表,且applycall是一次性传入参数

applycall 则是立即执行


实现一个call

  • 将函数设置为对象的属性
  • 指定this到函数并传入给定参数执行函数
  • 执行&删除这个函数,返回函数执行结果
Function.prototype.myCall = function(thisArg = window) {
    thisArg = thisArg ? Object(thisArg) : window;
    // this指向当前函数,thisArg是要绑定的对象,这里给对象绑定了属性fn,属性值是要执行的函数
    thisArg.fn = this;
    // 第一个参数为 this,所以要取剩下的参数
    const args = [...arguments].slice(1);
    // 执行函数
    const result = thisArg.fn(...args);
    // thisArg上并不存在fn,所以需要移除
    delete thisArg.fn;
    return result;
}

function foo() {
    console.log(this.name);
}
const obj = {
    name: 'litterStar'
}
const bar = function() {
    foo.myCall(obj);
}
bar();
// litterStar

实现一个apply

实现一个apply 过程很call类似,只是参数不同,

Function.prototype.myApply = function(thisArg = window) {
    thisArg.fn = this;
    let result;
    // 判断是否有第二个参数
    if(arguments[1]) {
        // apply方法调用的时候第二个参数是数组,所以要展开arguments[1]之后再传入函数
        result = thisArg.fn(...arguments[1]);
    } else {
        result = thisArg.fn();
    }
    delete thisArg.fn;
    return result;
}

bind

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

Function.prototype.myBind = function(thisArg) {
    thisArg = thisArg ? Object(thisArg) : window;
    // 保存当前函数的this
    const fn = this;
    // 保存原先的参数
    const args = [...arguments].slice(1);
    // 返回一个新的函数
    return function() {
        // 再次获取新的参数
        const newArgs = [...arguments];
        /**
         * 1.修改当前函数的this为thisArg
         * 2.将多次传入的参数一次性传入函数中
        */
        return fn.apply(thisArg, args.concat(newArgs))
    }
}

const obj1 = {
    name: 'litterStar',
    getName() {
        console.log(this.name)
    }
}
const obj2 = {
    name: 'luckyStar'
}

const fn = obj1.getName.myBind(obj2)
fn(); // luckyStar
  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序媛小y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值