60 秒回答模板

JavaScript 的 this 由调用方式决定。默认调用在非严格模式下通常指向全局对象,严格模式下是 undefined;obj.fn() 是隐式绑定,this 指向调用点左侧对象;call、apply、bind 是显式绑定;new 调用时 this 指向新创建的实例;箭头函数没有自己的 this,会捕获定义时外层词法 this,不能被 call、apply、bind 改变。判断时先看是不是 new,再看显式绑定,再看对象调用,最后看默认绑定,箭头函数单独按词法作用域处理。

考点 核心机制与工程取舍
难度 中高频面试题
回答目标 按定义、机制、场景讲清楚

深入解析

01

默认绑定

普通函数直接调用 fn() 时没有调用者。严格模式下 this 是 undefined,非严格模式下浏览器中可能指向 window,模块和运行环境会影响表现。

02

隐式绑定

通过 obj.fn() 调用时,this 指向最后一个调用点对象。链式属性要看真正调用函数的点,例如 a.b.fn() 中 this 通常是 b。

03

显式绑定

call 和 apply 立即调用函数并指定 this,区别在参数传递形式;bind 返回一个绑定后的新函数,之后调用时 this 通常保持绑定值。

04

new 绑定

new 调用构造函数时会创建新对象,把该对象绑定为 this,并连接原型。构造函数如果显式返回对象,则返回该对象;否则返回新实例。

05

箭头函数

箭头函数没有自己的 this、arguments、super 和 new.target。它的 this 来自定义时外层作用域,所以不能用 call/apply/bind 改变,也不能作为构造函数 new。

06

丢失绑定场景

把 obj.fn 赋值给变量、作为回调单独传入,调用点就可能变成默认绑定。常见修复是 bind、箭头函数包一层,或在类字段中使用箭头函数。

易错点

  • 不要说 this 指向函数定义所在对象。普通函数 this 取决于调用点。
  • 不要忘记严格模式下默认绑定是 undefined,而不是全局对象。
  • 不要试图用 call/apply 改变箭头函数 this,它没有自己的 this。
  • 不要忽略方法被赋值或作为回调传递后的隐式绑定丢失。

面试官追问

this 看定义位置还是调用位置?

普通函数看调用位置,也就是谁以什么方式调用它。箭头函数例外,它看定义时外层词法 this。

call、apply、bind 区别是什么?

call 和 apply 会立即执行,call 参数逐个传,apply 用数组或类数组传;bind 不立即执行,而是返回一个绑定 this 和部分参数的新函数。

new 和 bind 同时出现谁优先?

new 绑定优先级高。对绑定函数使用 new 时,this 指向新实例,而不是 bind 指定的对象。

为什么方法作为回调传出去 this 会丢?

因为调用点变了。obj.fn 传出去后如果被当作普通函数调用,就不再通过 obj 调用,隐式绑定丢失。