call和apply立即执行函数,区别在于参数以逐个或数组形式传入;bind返回永久绑定this的新函数,支持参数预设且不立即执行。

显式绑定指的是通过 call、apply、bind 主动指定函数执行时的 this 值。三者核心目标一致,但行为逻辑和适用场景差异明显。
参数传递方式:数组 vs 逐个 vs 预设
这是最直观的区别,直接影响你如何组织参数:
-
apply:第二个参数必须是数组或类数组(如
arguments),适合参数动态生成或已存在数组中,比如Math.max.apply(null, [1,5,3]) -
call:后续参数逐个列出,适合参数明确、数量固定,比如
func.call(obj, 'a', 'b', 123) -
bind:后续参数也是逐个传,但这些参数会被“冻结”进新函数,称为预设参数(柯里化),比如
const logUser = console.log.bind(console, '[USER]'),之后调用logUser('login')相当于console.log('[USER]', 'login')
执行时机:立即执行 vs 延迟执行
决定你是在“此刻调用”,还是“准备好了再调用”:
-
call和apply都是立即执行函数,并返回原函数的执行结果 -
bind不执行函数,只返回一个新函数,这个函数的this和部分参数已被固化,可多次复用或传给回调、定时器、事件监听器等异步场景 - 例如:给按钮绑定点击事件时,若直接写
btn.addEventListener('click', obj.handleClick.call(obj))就错了——它会立刻执行一次;正确做法是btn.addEventListener('click', obj.handleClick.bind(obj))
this 绑定的持久性:临时 vs 永久
关系到绑定是否会被后续调用覆盖:
-
call和apply是一次性临时绑定,不影响原函数,也不影响其他调用 -
bind创建的是永久绑定的新函数:即使再用call或apply尝试改this,只要不是用new调用,绑定的this就不会变 - 注意:箭头函数没有自己的
this,所以对它使用这三者无效,this始终由外层作用域决定
典型实用场景举例
理解区别后,关键看怎么用得准:
- 借用数组方法:对象有类似数组的结构(如
arguments或 DOM 集合),用Array.prototype.slice.call(arguments)转成真数组 - 求数组极值:
Math.max(...arr)是现代写法,但兼容旧环境就得用Math.max.apply(null, arr) - 事件处理与回调:需要保持上下文时,优先选
bind;若只是单次调用且参数已知,call更简洁 - 构造柯里化函数:比如封装 API 请求,
const getUser = apiRequest.bind(null, 'GET', '/users'),后续只需传 ID











