面试官:说说call、apply、bind是如何改变this的

💡 原文中文,约5500字,阅读约需13分钟。
📝

内容提要

本文介绍了JavaScript中this的显式绑定的三种方法:call、apply和bind,它们可以改变函数中this的指向。call和apply的区别在于参数的传递方式不同,bind则是创建一个新的函数并绑定this。文章还讨论了call、apply和bind在调用和结合new操作符时的影响。掌握这些基础知识对于理解JavaScript中的执行上下文、词法作用域和闭包非常重要。

🔎

延伸解读

手写实现的核心思路

文章通过手写 call、apply、bind 来揭示其内部机制。核心思路是将函数作为上下文对象的临时属性,然后通过该对象调用函数,从而改变 this 指向。call 和 apply 的实现类似,区别在于参数处理:call 使用剩余参数,apply 接受参数数组。bind 则返回一个新函数,内部通过 apply 绑定 this 并合并参数,同时需处理 new 调用的情况。

bind 的链式绑定特性

文章通过测试用例展示了 bind 的链式绑定行为:被 bind 绑定后的函数再次使用 bind 时,新传入的 thisArg 会被忽略,但之前绑定的参数仍然有效。这是因为新函数的 this 已经由第一次 bind 确定,后续 bind 无法覆盖。这一特性与 MDN 描述一致,理解它有助于避免在实际开发中误用 bind 导致 this 指向不符合预期。

new 调用时 bind 的 this 被忽略

当使用 new 调用 bind 绑定的函数时,bind 提供的 this 值会被忽略,函数内部的 this 指向新创建的实例。文章通过示例说明,此时参数会正常传递,且实例能继承原函数的原型方法。这是因为 new 操作符会创建一个新对象,并将其作为 this 执行构造函数,而 bind 绑定的 this 在此场景下不生效。

❓

Q&A

call、apply和bind的主要区别是什么?

call和apply的区别在于参数的传递方式,call接受多个参数,而apply接受一个参数数组;bind则是创建一个新的函数并绑定this。

如何使用call方法改变this的指向?

使用call方法时,第一个参数是要绑定的this值,后面的参数是传入函数执行的参数,调用时直接执行函数。

apply方法的参数传递方式是怎样的?

apply方法接受两个参数,第一个是this值,第二个是一个数组,数组中的元素作为参数传递给函数。

bind方法的返回值是什么?

bind方法返回一个新的函数,该函数绑定了this和固定参数,但不会立即执行。

使用new操作符调用bind绑定的函数会有什么影响?

使用new操作符调用bind绑定的函数时,bind提供的this值会被忽略,参数会正常传递执行。

call和bind在执行时有什么不同?

call在绑定this时立即执行函数,而bind则返回一个新的函数供后续执行,不会立即执行。

🏷️

标签

➡️

继续阅读