搞懂 Javascript 中的this(包含apply、call、bind)
内容提要
JavaScript中的关键字this是一个复杂机制,指向执行时的当前对象。其绑定方式取决于函数的调用方式,包括作为对象方法、普通函数、构造器调用以及使用call或apply。eval和with可以在运行时修改作用域,但不推荐使用。
延伸解读
this 绑定的动态性
this 的指向并非在函数定义时确定,而是在函数调用时根据调用方式动态绑定。这意味着同一个函数,如果以不同方式调用,this 可能指向不同的对象。理解这一点是掌握 this 的关键,也能帮助开发者避免因调用方式改变而导致的意外行为。
方法拷贝导致 this 丢失
当对象的方法被单独赋值给一个变量并调用时,该方法内的 this 会丢失原本的指向,转而指向全局对象(浏览器中为 window)。这是因为调用方式变成了普通函数调用。在实际开发中,将方法作为回调传递时需特别注意,必要时使用 bind 固定 this。
构造器返回对象的特殊情况
使用 new 调用构造器时,如果构造器显式返回一个对象,那么 new 表达式的结果将是这个返回的对象,而不是构造器内部 this 所引用的新对象。如果返回的是非对象类型(如字符串、数字),则忽略返回值,仍返回 this 所引用的对象。这一细节在编写工厂函数或继承时需留意。
call、apply 与 bind 的区别
call 和 apply 都能立即执行函数并改变 this 指向,区别在于参数传递方式:apply 接受一个数组或类数组作为参数,call 接受一系列单独的参数。bind 则不同,它返回一个绑定了 this 的新函数,不会立即执行。bind 常用于事件处理或回调中固定 this。
Q&A
JavaScript中的this指向什么?
this指向执行时的当前对象。
如何使用call和apply改变this的指向?
call和apply可以动态改变函数的this指向,apply接受数组作为参数,call接受不固定数量的参数。
构造器调用时this指向哪里?
构造器调用时,this指向返回的对象,除非显式返回一个对象。
普通函数调用时this指向哪个对象?
普通函数调用时,this指向全局对象。
bind方法的作用是什么?
bind方法修改this后返回一个新的函数,但不会立即执行。
eval和with在JavaScript中有什么风险?
eval和with可以在运行时修改作用域,但不推荐使用,可能导致性能问题和难以预料的错误。