真实面经题目 · 原创解析
this 绑定说说
这题考察 this 的调用点规则、绑定优先级和箭头函数词法 this。回答要强调看调用方式,不是看函数声明位置。
真实面经题目 · 原创解析
这题考察 this 的调用点规则、绑定优先级和箭头函数词法 this。回答要强调看调用方式,不是看函数声明位置。
JavaScript 的 this 由调用方式决定。默认调用在非严格模式下通常指向全局对象,严格模式下是 undefined;obj.fn() 是隐式绑定,this 指向调用点左侧对象;call、apply、bind 是显式绑定;new 调用时 this 指向新创建的实例;箭头函数没有自己的 this,会捕获定义时外层词法 this,不能被 call、apply、bind 改变。判断时先看是不是 new,再看显式绑定,再看对象调用,最后看默认绑定,箭头函数单独按词法作用域处理。
普通函数直接调用 fn() 时没有调用者。严格模式下 this 是 undefined,非严格模式下浏览器中可能指向 window,模块和运行环境会影响表现。
通过 obj.fn() 调用时,this 指向最后一个调用点对象。链式属性要看真正调用函数的点,例如 a.b.fn() 中 this 通常是 b。
call 和 apply 立即调用函数并指定 this,区别在参数传递形式;bind 返回一个绑定后的新函数,之后调用时 this 通常保持绑定值。
new 调用构造函数时会创建新对象,把该对象绑定为 this,并连接原型。构造函数如果显式返回对象,则返回该对象;否则返回新实例。
箭头函数没有自己的 this、arguments、super 和 new.target。它的 this 来自定义时外层作用域,所以不能用 call/apply/bind 改变,也不能作为构造函数 new。
把 obj.fn 赋值给变量、作为回调单独传入,调用点就可能变成默认绑定。常见修复是 bind、箭头函数包一层,或在类字段中使用箭头函数。
普通函数看调用位置,也就是谁以什么方式调用它。箭头函数例外,它看定义时外层词法 this。
call 和 apply 会立即执行,call 参数逐个传,apply 用数组或类数组传;bind 不立即执行,而是返回一个绑定 this 和部分参数的新函数。
new 绑定优先级高。对绑定函数使用 new 时,this 指向新实例,而不是 bind 指定的对象。
因为调用点变了。obj.fn 传出去后如果被当作普通函数调用,就不再通过 obj 调用,隐式绑定丢失。