JS bind/call/apply

MDN: bind | call | apply

介绍

call(thisArg, arg1, arg2, /* …, */ argN)

使用指定的 thisArg 作为 this 来调用函数

在非严格模式下,thisArg 会做如下的转换

  • 如果是 null / undefined:改为全局对象

  • 如果是原始类型,改为对应的包装类型

Playground:https://stackblitz.com/edit/singee-kb-js-call?file=index.js

apply(thisArg, argsArray?)

利用指定的 thisArg 作为 this 来调用函数

这个函数与 call 的唯一区别是第二个参数使用数组而不是多个参数

argsArray 除了传递真数组外,还可以传递任何类数组(任何存在 length 属性并且有对应的 0~length-1 整数属性的对象),例如 arguments

JS 的函数参数个数实际上是有限制的(例如数万个参数),使用 apply 会导致这个限制可能在极端情况下被超出,而超出时的解释器行为是未定义的(大多会抛出异常,也可能会只处理某部分)

MDN | Playground

bind(thisArg, arg1, arg2, /* …, */ argN)

bind 用于创建一个已预设置了 thisArg 和若干个参数的新函数(类似柯里化

挑战

手动实现 bind

要点:

  1. 正确处理 this 绑定

  2. 正确处理 new

Function.prototype.myBind = function (thisArg, ...bindArgs) { const f = this; return function (...args) { if (new.target !== undefined) { const obj = {}; f.apply(obj, [...bindArgs, ...args]); return obj; } return f.apply(thisArg, [...bindArgs, ...args]); }; };

Playground (with test)