简单实现call,apply,bind的代码

首先,先来总结一下这三者的共同点与区别:

  • 三者都是为了改变this的指向
  • callapply其实差不多,都是一次性传入所有参数,调用后马上执行对应的函数,只是前者接收的是参数列表,但后者接收的是一个数组,代码实现中,除了接收参数不同,其他完全一致
  • bind返回一个改变了this指向的函数,在调用过程中,可以先传入部分固定参数,动态参数可以在调用返回的函数再传入,即可以分开多次传入参数,且返回的函数不会立即执行,开发人员可以根据需求来进行调用返回的函数

注意: 在实现过程中,一定要考虑到传入的对象为nullundefined、原始类型的情况,详情请看代码。

代码如下( call):
function test(a, b) {
  console.log('test', this, a, b);
  return a + b;
}

Function.prototype.myCall = function (ctx, ...args) {
  // 由于js会在两种环境下运行:浏览器(window)和Node,故使用globalThis
  ctx = ctx === null || ctx === undefined ? globalThis : Object(ctx);
  let uniqueKey = Symbol('test');
  Object.defineProperty(ctx, uniqueKey, {
    enumerable: false,
    value: this
  });
  return ctx[uniqueKey](...args);
};

let res = test.myCall({}, 12, 13);

console.log('res = ', res); // 25
代码如下( apply):
function test(a, b) {
  console.log('test', this, a, b);
  return a + b;
}

Function.prototype.myApply = function (ctx, args) {
  // 由于js会在两种环境下运行:浏览器(window)和Node,故使用globalThis
  ctx = ctx === null || ctx === undefined ? globalThis : Object(ctx);
  let uniqueKey = Symbol('test');
  Object.defineProperty(ctx, uniqueKey, {
    enumerable: false,
    value: this
  });
  return ctx[uniqueKey](...args);
};

let res = test.myApply ({}, 12, 13);

console.log('res = ', res); // 25
代码如下( bind):
function test(a, b) {
  console.log('test', this, a, b);
  return a + b;
}

Function.prototype.myBind = function (ctx, ...args1) {
  // 由于js会在两种环境下运行:浏览器(window)和Node,故使用globalThis
  ctx = ctx === null || ctx === undefined ? globalThis : Object(ctx);
  let uniqueKey = Symbol('test');
  Object.defineProperty(ctx, uniqueKey, {
    enumerable: false,
    value: this
  });
  return function (...args2) {
    return ctx[uniqueKey](...args1, ...args2);
  };
};
let backFunc = test.myBind({}, 12);
let res = backFunc(88);
console.log('res = ', res); // 100

ps:如有不足,欢迎点评,谢谢!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值