在这里插入图片描述

🤍 前端开发工程师、技术日更博主、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠 牛客高级专题作者、打造专栏《前端面试必备》《2024面试高频手撕题》《前端求职突破计划》
🍚 蓝桥云课签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》《带你从入门到实战全面掌握 uni-app》

引言

在 JavaScript 里,this 是一个特殊的关键字,它的指向是动态且灵活的,依据不同的使用场景会有不同的指向。深入理解 this 的指向机制,对于编写高效、稳定且易于维护的 JavaScript 代码至关重要。本文将深入探讨 this 在不同场景下的指向规则。

全局作用域中的 this

在全局作用域(也就是在任何函数外部)使用 this 时,它指向的是全局对象。在浏览器环境中,全局对象是 window 对象;而在 Node.js 环境里,全局对象是 global 对象。

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

// 定义一个全局变量
var globalVar = 'I am a global variable';
console.log(this.globalVar); // 'I am a global variable'

在上述代码中,this 指向全局对象 window,所以 this 可以访问到全局变量。

函数内部的 this

普通函数调用

当函数作为普通函数调用时,this 指向全局对象。不过,在严格模式下,this 的值为 undefined

// 非严格模式
function normalFunction() {
    console.log(this); // 浏览器环境中指向 window
}
normalFunction();

// 严格模式
function strictFunction() {
    'use strict';
    console.log(this); // undefined
}
strictFunction();

方法调用

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

const person = {
    name: 'John',
    sayHello: function() {
        console.log(`Hello, my name is ${this.name}`);
    }
};

person.sayHello(); // 'Hello, my name is John'

在这个例子中,sayHello 方法中的 this 指向 person 对象,所以能够访问 person 对象的 name 属性。

构造函数调用

当函数作为构造函数调用(使用 new 关键字)时,this 指向新创建的对象。

function Person(name) {
    this.name = name;
    this.sayHello = function() {
        console.log(`Hello, my name is ${this.name}`);
    };
}

const newPerson = new Person('Jane');
newPerson.sayHello(); // 'Hello, my name is Jane'

这里,new Person('Jane') 创建了一个新的 Person 对象,构造函数中的 this 就指向这个新对象。

箭头函数中的 this

箭头函数不会创建自己的 this,它的 this 值继承自外层函数。

const obj = {
    name: 'ArrowObj',
    sayName: function() {
        const arrowFunction = () => {
            console.log(this.name);
        };
        arrowFunction();
    }
};

obj.sayName(); // 'ArrowObj'

在上述代码中,箭头函数 arrowFunctionthis 继承自 sayName 方法的 this,也就是 obj 对象。

改变 this 指向的方法

call() 方法

call() 方法允许你指定函数调用时 this 的值,并且可以传递参数。

function greet(message) {
    console.log(`${message}, my name is ${this.name}`);
}

const person1 = { name: 'Alice' };
greet.call(person1, 'Hi'); // 'Hi, my name is Alice'

apply() 方法

apply() 方法和 call() 方法类似,区别在于 apply() 接收一个数组作为参数。

function greet(message) {
    console.log(`${message}, my name is ${this.name}`);
}

const person2 = { name: 'Bob' };
greet.apply(person2, ['Hello']); // 'Hello, my name is Bob'

bind() 方法

bind() 方法会创建一个新的函数,在调用时 this 值会被绑定到指定的对象上。

function greet(message) {
    console.log(`${message}, my name is ${this.name}`);
}

const person3 = { name: 'Charlie' };
const boundGreet = greet.bind(person3);
boundGreet('Hey'); // 'Hey, my name is Charlie'

事件处理函数中的 this

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

<!DOCTYPE html>
<html lang="en">

<body>
    <button id="myButton">Click me</button>
    <script>
        const button = document.getElementById('myButton');
        button.addEventListener('click', function() {
            console.log(this); // 指向按钮元素
        });
    </script>
</body>

</html>

在这个例子中,点击按钮时,事件处理函数中的 this 指向按钮元素。

总结

JavaScript 中 this 的指向是一个复杂且关键的概念,它依据不同的使用场景会有不同的指向。在全局作用域中,this 指向全局对象;普通函数调用时,this 指向全局对象(严格模式下为 undefined);方法调用时,this 指向调用该方法的对象;构造函数调用时,this 指向新创建的对象;箭头函数的 this 继承自外层函数。此外,还可以使用 call()apply()bind() 方法来改变 this 的指向。在事件处理函数中,this 通常指向触发事件的元素。只有深入理解并熟练运用这些规则,才能在编写 JavaScript 代码时准确把握 this 的指向,避免出现意外的错误。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐