Javascript中的call/apply/bind

前言

Javascript中改变this指向的方法有call、apply、bind。它们都可以改变this的指向,但是也有一些不同。本文会讲解一下它们之间的区别。以及如何模拟实现cal、apply、bind方法


一、call、apply、bind的区别

call、apply、bind区别很简单

1. call调用时改变this的指向,第一个参数是需要改变this指向的目标,后面参数为函数调用所需参数

var person = {
  firstName: "Lee",
  lastName: "Jordan",
};

function getFullName(separator) {
  return `${this.firstName}${separator}${this.lastName}`;
}
// 如果需要传入第三个参数 可以在“-”加逗号后添加, 依次累加 例如 getFullName.call(person, "-", argument)
console.log(getFullName.call(person, "-"));

2. apply调用时改变this的指向,第一个参数也是 需要改变this指向的目标,第二参数为一个函数调用所需参数的数据

var person = {
  firstName: "Lee",
  lastName: "Jordan",
};

function getFullName(separator) {
  return `${this.firstName}${separator}${this.lastName}`;
}
// call 和 apply 的区别 一个是以参数占位方式传递函数需要的参数 一个是一个参数列表数组的形式给到函数
console.log(getFullName.call(person, ["-"]));

3. bind调用时改变this的指向并且返回一个新的函数, this的指向将不能再次更改。第一次调用时第一个参数是需要改变this指向的目标,后面的参数会合并。具体看看例子。

// 第一次绑定的this是this value 后续再使用call\apply\bind都无法改变thi的指向
// 每次绑定的第二位参数开始后面的参数将会合并 1 2 3 4 5 6
function log(...args) {
  console.log(this, ...args);
}

const boundLog = log.bind("this value", 1, 2);

const boundLog2 = boundLog.bind("new this value", 3, 4);

boundLog2(5, 6); // [String: 'this value'] 1 2 3 4 5 6

二、模拟实现call

Function.prototype.selfCall = function (thisArg, ...args) {
  // 判定绑定目标的边界
  var thisArg =
    thisArg === null || thisArg === undefined ? globalThis : Object(thisArg);
  var fn = this;
  thisArg.fn = fn;
  const result = thisArg.fn(...args);
  delete thisArg.fn;
  return result;
};

三、模拟实现apply 

Function.prototype.selfApply = function (thisArg, args) {
  var args = args === undefined ? [] : args,
    fn = this;
  if (!Array.isArray(args)) {
    throw new Error("参数类型不对");
  }
  var thisArg =
    thisArg === null || thisArg === undefined ? globalThis : Object(thisArg);
  thisArg.fn = fn;
  const result = thisArg.fn(...args);
  delete thisArg.fn;
  return result;
};

四、模拟实现bind 

Function.prototype.selfBind = function (thisArg, ...argsArray) {
  var _this = this;
  var context =
    thisArg === null || thisArg === undefined ? globalThis : Object(thisArg);
  return function fn(...args) {
    const allArgs = [...argsArray, ...args];
    // 防止new的调用
    if (this instanceof fn) {
      return new _this(...allArgs);
    }
    // 普通函数的调用
    return _this.apply(context, allArgs);
  };
};

总结

本文主要讲了call/apply/bind的区别,以及模拟实现了call/apply/bind方法。模拟的这些方法还有一些边界没有判断。发现了可以在上述代码基础上添加。结束收工!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值