小白自学:js中的一座this大山,真的难

128 阅读4分钟

在 JavaScript 中,this 是一个非常重要且常用的关键字,它在不同的上下文中具有不同的含义。本文将深入探讨 this 的概念、工作原理以及使用场景,通过详细的解释和丰富的示例帮助你更好地理解和掌握 this

1. 概念介绍

this 是一个指向当前执行代码的对象的关键字。它的值取决于代码所在的执行上下文,可以分为以下几种情况:

  • 全局上下文中: 在全局作用域中,this 指向全局对象(在浏览器环境中通常是 window 对象)。
  • 函数上下文中: 在函数内部,this 的值取决于函数的调用方式。
  • 对象方法中: 在对象的方法中,this 指向调用该方法的对象。
  • 构造函数中: 在构造函数中,this 指向通过 new 关键字创建的新对象。
  • 事件处理函数中: 在事件处理函数中,this 指向触发事件的 DOM 元素。
  • 箭头函数中: 在箭头函数中,this 的值由包含箭头函数的词法作用域决定,而不是调用时的上下文。
  • 闭包中的 this 在闭包中,this 的值取决于函数的调用方式,如果函数被作为普通函数调用,this 指向全局对象。
  • 显式指定 this 可以使用 call()apply()bind() 方法显式地指定函数内部的 this 指向某个对象。
  • 注意事项: 在严格模式下,全局上下文中的 thisundefined;在闭包中避免依赖于 this;使用箭头函数可以避免 this 的意外行为。

2. 示例演示

全局上下文

console.log(this === window); // true(在浏览器环境中)

函数上下文

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

greet(); // window(在浏览器环境中)

对象方法

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

person.greet(); // Alice

构造函数

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

let person1 = new Person('Bob');
console.log(person1.name); // Bob

事件处理函数

htmlCopy code
<button id="myButton">Click me</button>
<script>
    document.getElementById('myButton').addEventListener('click', function() {
        console.log(this); // button 元素
    });
</script>

箭头函数

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

obj.greet(); // Alice

闭包中的 this

javascriptCopy code
let obj = {
    name: 'Alice',
    sayName: function() {
        let innerFunction = function() {
            console.log(this.name);
        };
        innerFunction();
    }
};

obj.sayName(); // 在内部函数中,this 指向全局对象(浏览器环境下),因为内部函数不是作为对象的方法

使用 call()apply()bind() 显式指定 this

javascriptCopy code
function sayHello() {
    console.log('Hello, my name is ' + this.name);
}

let obj = { name: 'Alice' };

sayHello.call(obj); // 使用 call() 方法显式指定函数内部的 this 指向 obj 对象,输出 'Hello, 

3. 注意事项

  • 在严格模式下,全局上下文中的 this 将会是 undefined,而不是全局对象。
  • 在函数中使用 this 时,它的值取决于函数的调用方式。使用 call()apply()bind() 方法可以显式地指定函数内部的 this 值。
  • 在箭头函数中,this 的值由包含箭头函数的词法作用域决定,而不是调用时的上下文。

以上内容覆盖了 JavaScript 中 this 的主要方面和常见用法,包括在不同上下文中的行为、示例演示以及一些注意事项。虽然这些内容涵盖了 this 的核心概念,但是 this 是一个相对复杂且灵活的概念,在实际开发中可能会遇到更多的情况和细节。因此,需要不断练习和实践,以深入理解和掌握 this 的使用。

4.this绑定的规则

我们通过上面的例子可以找到一些规律,从而找到this的绑定规则。通过结合这些规则,我们可以更好地理解在不同情况下 this 的指向,从而更有效地编写代码。

  1. 默认绑定: 当函数以独立函数调用的方式执行时,this 指向全局对象(在浏览器环境中通常是 window 对象)。这种绑定规则适用于那些不属于任何对象的函数。
  2. 隐式绑定: 当函数作为对象的方法调用时,this 指向调用该方法的对象。这意味着函数内部的 this 关键字将绑定到函数所属的对象上。
  3. 隐式丢失: 当函数被一个对象所拥有,但是在调用时丢失了对象的上下文时,this 不再指向该对象,而是指向全局对象或者 undefined。这种情况通常发生在将对象方法作为参数传递给另一个函数,或者在定时器、事件处理函数等特殊情况下。
  4. 显示绑定: 通过 call()apply()bind() 方法,我们可以显式地指定函数内部的 this 指向某个对象。这样可以在不改变原函数定义的情况下,动态地改变函数执行时的上下文。
  5. new 绑定: 当使用 new 关键字调用构造函数时,this 指向通过构造函数创建的新对象。这种绑定规则用于创建和初始化新的对象实例。

结语

this 是 JavaScript 中一个重要的概念,对于理解函数调用和对象方法的执行至关重要。通过本文的介绍和示例,相信你对 this 的概念有了更深入的理解。在实际编程中,多做练习和实践可以帮助你更加熟练地掌握 this 的使用。