什么是this关键字_它的指向规则是什么【教程】

3次阅读

this 的指向由函数调用时的上下文动态决定:普通调用时非严格模式指向全局对象、严格模式为 undefined;对象点调用时指向该对象;箭头函数继承外层 this;call/apply/bind 和 new 可显式改变 this。

什么是this关键字_它的指向规则是什么【教程】

this 的指向不是由函数定义时决定的,而是由函数**调用时的上下文**动态确定的。它没有固定值,搞错 this 指向是 javaScript 中最常见、最隐蔽的 bug 来源之一。

普通函数调用时,this 指向全局对象(非严格模式)或 undefined(严格模式)

这是最容易踩坑的场景:把对象方法赋值给变量后单独调用。

const obj = {   name: 'Alice',   say() { console.log(this.name); } }; const fn = obj.say; fn(); // 非严格模式下输出 undefined(浏览器中 this 指向 window,但 window.name 通常为空);严格模式下报错 "Cannot read property 'name' of undefined"

原因:此时 fn() 是“普通调用”,不带任何上下文绑定。

  • 浏览器非严格模式下,this 指向 window
  • 在严格模式或 node.js 环境中,thisundefined
  • es6 模块默认启用严格模式,所以几乎总是 undefined

对象方法调用时,this 指向该对象(但仅限“点调用”)

只有形如 obj.method() 这种直接通过属性访问符调用,才触发“对象方法绑定”规则。

const obj = { name: 'Bob', say() { console.log(this.name); } }; obj.say(); // 输出 'Bob'

注意以下情况不适用:

  • (obj.say)() —— 圆括号不改变调用方式,仍是普通调用(this 失效)
  • setTimeout(obj.say, 100) —— 回调函数被提取后独立调用
  • [obj.say][0]() —— 数组取值再调用,也丢失绑定

箭头函数没有自己的 this,它继承外层函数作用域的 this

箭头函数的 this 是词法绑定的,无法被 call/apply/bind 修改,也不能作为构造函数使用。

const obj = {   name: 'Charlie',   regular() {      console.log('regular:', this.name);      const arrow = () => console.log('arrow:', this.name);     arrow(); // 输出 'arrow: Charlie',因为继承了 regular 的 this   } }; obj.regular();

典型误用:

  • 事件监听器中写 el.addEventListener('click', () => this.handleClick()) —— this 不会自动指向组件实例,得靠外层函数绑定好再传入
  • 试图用 arrow.bind(obj) 强行改 this —— 无效,语法合法但无效果

显式绑定与 new 调用会覆盖默认规则

callapplybind 可强制指定 thisnew 调用则让 this 指向新创建的实例。

  • func.call(obj, 1, 2)thisobj
  • const bound = func.bind(obj); bound() → 永远指向 obj(即使后续再 call 其他对象也无效)
  • new Func()this 是新生成的空对象,且返回值优先级高于函数内 return 的非对象值

注意:bind 返回的函数如果再被 new 调用,this 绑定会被忽略——这是少数能“绕过” bind 的情况。

真正难的不是记住规则,而是在嵌套回调、异步链、类方法提取、第三方库集成时,快速判断当前执行this 到底是谁。建议在不确定时,直接 console.log(this),比查文档更快。

text=ZqhQzanResources