授课语音

学习 this 规则与使用

this 是JavaScript中非常特殊且复杂的一个概念,它的值取决于函数的调用方式。理解 this 的规则是掌握JavaScript的重要步骤,能够帮助我们更好地处理对象和函数的上下文。


1. this 的基本概念

this 是一个关键字,代表当前执行上下文中的对象。具体来说,this 的值取决于函数的调用方式。


2. this 的常见用法和规则

2.1 全局上下文中的 this

在全局执行环境中,this 指向全局对象。在浏览器中,this 指向 window 对象。

console.log(this); // 在浏览器中输出 window 对象

中文注释

  • 在全局作用域中,this 默认指向全局对象。在浏览器环境下,全局对象是 window

2.2 函数调用中的 this

在普通的函数调用中,this 指向全局对象(在浏览器中是 window)。

function showThis() {
    console.log(this);
}

showThis(); // 在浏览器中输出 window 对象

中文注释

  • 普通函数调用中,this 指向全局对象。如果在浏览器中运行,this 会指向 window 对象。

2.3 对象方法中的 this

当函数作为对象的方法调用时,this 指向调用该方法的对象。

let person = {
    name: 'Alice',
    greet: function() {
        console.log(this.name);
    }
};

person.greet(); // 输出 "Alice"

中文注释

  • 在对象方法中,this 指向调用该方法的对象,在这里是 person 对象。

2.4 构造函数中的 this

在构造函数中,this 指向新创建的实例对象。

function Person(name) {
    this.name = name;
}

let alice = new Person('Alice');
console.log(alice.name); // 输出 "Alice"

中文注释

  • 在构造函数中,this 指向新创建的实例对象,因此 this.name 会被赋值。

2.5 箭头函数中的 this

箭头函数与普通函数的一个重要区别是,箭头函数没有自己的 this,它会继承外部上下文中的 this

let person = {
    name: 'Alice',
    greet: function() {
        setTimeout(() => {
            console.log(this.name);
        }, 1000);
    }
};

person.greet(); // 输出 "Alice"

中文注释

  • 在箭头函数中,this 不会被重新绑定,而是继承外部作用域中的 this。在这个例子中,this.name 仍然指向 person 对象。

2.6 call()apply()bind()

这三个方法可以显式地改变 this 的指向。它们的区别在于传递参数的方式。

2.6.1 call() 方法

call() 方法调用一个函数,并且明确指定 this 的值及传递给函数的参数。

function greet() {
    console.log('Hello, ' + this.name);
}

let person = { name: 'Alice' };
greet.call(person); // 输出 "Hello, Alice"

中文注释

  • 使用 call() 方法,可以显式地将 this 绑定到指定对象。

2.6.2 apply() 方法

apply() 方法与 call() 类似,不同的是它接受的是一个数组作为参数。

function greet(age) {
    console.log('Hello, ' + this.name + '. You are ' + age + ' years old.');
}

let person = { name: 'Alice' };
greet.apply(person, [25]); // 输出 "Hello, Alice. You are 25 years old."

中文注释

  • apply()call() 类似,但它接受一个数组作为参数。

2.6.3 bind() 方法

bind() 方法返回一个新的函数,这个新函数的 this 永远绑定到指定的对象上。

function greet() {
    console.log('Hello, ' + this.name);
}

let person = { name: 'Alice' };
let greetPerson = greet.bind(person);
greetPerson(); // 输出 "Hello, Alice"

中文注释

  • bind() 方法返回一个新的函数,新的函数会永久绑定到指定的对象。

3. this 在不同场景中的应用

3.1 this 和事件处理

在事件处理函数中,this 指向触发事件的 DOM 元素。

let button = document.querySelector('button');
button.addEventListener('click', function() {
    console.log(this); // 输出被点击的 button 元素
});

中文注释

  • 在事件处理函数中,this 指向触发事件的元素。在这个例子中,this 会指向 button 元素。

3.2 this 和定时器

setTimeoutsetInterval 中,this 默认指向全局对象(在浏览器中是 window)。

setTimeout(function() {
    console.log(this); // 输出 window 对象
}, 1000);

中文注释

  • setTimeout 等定时器中,this 默认指向全局对象。如果是在浏览器中,this 会指向 window

3.3 this 与类(Class)中的使用

在 ES6 的类中,this 指向当前类的实例对象。

class Person {
    constructor(name) {
        this.name = name;
    }
    
    greet() {
        console.log('Hello, ' + this.name);
    }
}

let alice = new Person('Alice');
alice.greet(); // 输出 "Hello, Alice"

中文注释

  • 在类的方法中,this 指向当前类的实例对象。在这个例子中,this.name 会访问 Person 实例中的 name 属性。

4. 总结

  • this 的指向规则在 JavaScript 中非常重要,理解不同场景下 this 的指向能帮助我们编写更准确的代码。
  • this 在全局作用域中指向全局对象,在函数调用中通常指向全局对象,在对象方法中指向该对象,在构造函数中指向新创建的实例对象。
  • call()apply()bind() 方法可以显式地改变 this 的指向,灵活地控制函数执行上下文。
  • 箭头函数和普通函数的 this 行为不同,箭头函数继承外部 this,而普通函数会重新绑定 this

掌握 this 的使用规则,将有助于你在JavaScript开发中避免常见的陷阱,并能够灵活地处理各种上下文问题。

去1:1私密咨询

系列课程: