Skip to content

this小总结

作者:青见春山
发表于:2026-09-08
字数统计:1284 字
预计阅读5分钟

在JavaScript中,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指的是谁。普通函数(非箭头函数)的this值是在函数被调用时确定的

几种情况总结:

  1. 独立函数调用:非严格模式的普通函数直接调用时,this 会替换为 globalThis;严格模式下是 undefined。ES Module 默认处于严格模式。不能笼统记成“浏览器是 window、Node.js 是 global”,因为模块类型和运行环境都会影响结果。

    function foo() {
      return this;
    }
    console.log(foo() === globalThis); // 经典非严格 script 中为 true
  2. 对象方法调用: 当函数作为对象的方法被调用时,this值是该对象。

    const obj = {
      foo() {
        return this;
      }
    };
    console.log(obj.foo() === obj); // true
  3. 构造函数调用: 当函数作为构造函数(使用new关键字)调用时,this值是新创建的对象。

    构造函数内的属性和方法前面必须加this,表示当前对象的属性和方法

    new关键字作用:让 this 指向这个新的对象。

    function MyClass() {
      this成员 = '成员值';
    }
    const实例 = new MyClass();
    console.log(实例.成员); // '成员值'
  4. DOM 事件处理:用普通函数注册的监听器中,this 等于 event.currentTarget(注册监听器的元素),不一定是实际触发事件的 event.target

    html
    <button id="myButton">点击我</button>
    javascriptdocument.getElementById('myButton').onclick = function(event) {
      console.log(this === event.currentTarget); // true
    };
  5. apply、call 和 bind 方法applycallbind 方法可以用来设置this值。

    //apply方法
    调用函数,同时指定被调用函数中this的值
    //1.apply方法
            const person = {
                age: 19
            }
            function f(x,y){
                console.log(this)
                console.log(x + y)  //3
            }
            //调用函数
            f()
            f.apply()
            //改变this指向
            f.apply(person)
    
            // 与 call 的区别:apply 的第二个参数是数组或类数组对象,也可以是 null/undefined
            f.apply(person,[1,2])
    
    
    
    
    
    //call方法
    调用函数,同时指定被调用函数中this的值
    
        fun.call(thisArg,arg1,arg2,...)
        //thisArg,在fun函数运行时指定的this值
        //arg1,arg2 : 传递的其他参数
        //返回值就是函数的返回值,因为它就是调用函数
    
    示例代码:
    
        const obj = {
        uname:'pink'
        }
        function fn(x,y){
        console.log(this) //window
        }
        //使用函数的call方法
        fn.call(obj,1,2)
        //此时this指向obj这个对象
    
    //bind方法
  6. 箭头函数中使用:箭头函数没有自己的 this,而是按词法作用域使用外层环境的 this。它不是在定义时把某个“对象”永久绑定进去。

    const obj = {
      foo: function() {
        setTimeout(() => console.log(this), 1000);
      }
    };
    obj.foo(); // 输出obj
  7. 原型方法中的 this 仍由调用方式决定。instance.method() 通常指向实例,但把方法拆出来直接调用、用 call 调用或由其他对象借用时都会不同。

每一个构造函数都有一个prototype属性,指向一个对象,叫原型对象

把不变的方法定义在prototype对象上

function Star(starName,age){
	this.starName = starName
	this.age = age
}
Star.prototype.sing = function(){
	console.log(this.starName)
}

const lce = new Star('Lce',18)
lce.sing() // 调用点的接收者是 lce,因此 this === lce

箭头函数不可用:

1.定义对象的方法,且该方法内部包括this

对象的属性建议使用传统的写法定义,不要用箭头函数定义。

const cat = {
  lives: 9,
  jumps: () => {
    this.lives--;
  }
}

上例把需要动态接收者的对象方法写成箭头函数,因此得不到 cat 作为 this。顶层经典 script 中外层 this 常是 window,ES Module 中则是 undefined,所以不能一概写成“指向全局对象”。

2.需要动态this的时候,也不应使用箭头函数。

var button = document.getElementById('press');
button.addEventListener('click', () => {
  this.classList.toggle('on');
});

箭头函数会沿用外层 this,因此这里无法依赖 this.classList;在 ES Module 中通常会因 thisundefined 而报错。可改用普通函数读取 this/event.currentTarget,或在箭头函数中直接使用 button

定时器的this指向问题:

image-20240728222028326

普通函数的 this 由调用方式决定,箭头函数按词法作用域读取外层 this。浏览器定时器调用普通函数回调时 this 通常是 window,但 Node.js 中通常是 Timeout 对象,因此跨环境代码不要依赖定时器为回调提供的 this

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42

调用 foo.call({ id: 42 }) 时,foo 内部的 this 是该对象;随后创建的箭头函数捕获这个 this,所以稍后输出 42。关键是词法捕获发生在本次 foo 执行期间,而不是“箭头函数定义时所在的对象”。

image-20240725211457194

这个写的非常好,多看

image-20240727182518609