当前位置: 首页 > article >正文

【前端】JavaScript 中的 this 与全局对象 window深度解析


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: 前端

文章目录

  • 💯前言
  • 💯什么是 `this`?
    • `this` 的多样性
    • `this` 在全局环境中为什么指向 `window`
  • 💯构造函数中的 `this`
    • `this` 的指向
    • `instanceof` 检查
  • 💯思路总结:为何全局变量是 `window` 的属性?
    • 严格模式下的区别
  • 💯小结


在这里插入图片描述


💯前言

  • 在 JavaScript 中,this 是一个极为重要且复杂的关键字,其灵活的特性常常让初学者甚至中级开发者感到困惑,特别是在不同环境中,this 的指向可能会发生显著变化。在浏览器环境下,this 在全局作用域中通常指向 window 对象,这一点对于初次接触 JavaScript 的开发者来说尤其难以理解。本文将深入探讨 JavaScript 中 this 的工作原理,并解释为什么全局变量在浏览器中会成为 window 对象的属性。此外,我们还将分析严格模式下 this 的行为差异,以及在不同调用上下文中如何最佳实践 this 的使用。
    JavaScript在这里插入图片描述

💯什么是 this

在 JavaScript 中,this 是一个特殊的引用,通常用于指向当前的执行上下文或对象环境。this 的值并不是静态确定的,而是取决于函数的调用方式和调用位置。为了真正理解 this,我们需要深入了解 JavaScript 中不同调用方式所带来的上下文差异,以及它们对 this 指向的影响。
在这里插入图片描述


this 的多样性

JavaScript 中,this 的行为取决于其所处的执行上下文,以下是 this 常见的几种场景:

  1. 全局上下文
    在全局作用域中执行的代码(例如脚本最外层的代码),this 始终指向全局对象。在浏览器环境中,全局对象就是 window。例如:

    console.log(this); // 输出: window
    

    在这里插入图片描述

    在这个例子中,代码执行在全局上下文中,因此 this 指向全局对象 window。这是 JavaScript 语言设计中的一个基本概念,旨在提供一种便捷的方式来访问全局对象及其属性和方法。

  2. 函数调用
    当函数在非严格模式下被直接调用时,this 会默认指向全局对象 window。例如:

    function f1() {
        console.log(this);
    }
    f1(); // 输出: window
    

    在这里插入图片描述

    在上述代码中,f1() 函数是在全局环境中直接调用的,因此 this 指向全局对象 window。这种现象被称为“默认绑定”,是 JavaScript 中一种标准的绑定行为,确保函数在没有明确调用者的情况下,仍有一个合理的上下文。

  3. 对象方法调用
    当函数被作为对象的方法调用时,this 指向调用该函数的对象。如下所示:

    var obj = {
        name: 'Alice',
        greet: function() {
            console.log(this.name);
        }
    };
    obj.greet(); // 输出: Alice
    

    在这里插入图片描述
    在此例中,greet 方法是通过对象 obj 调用的,因此 this 指向调用方法的对象 obj,并输出 Alice。这种情况下,this 的指向是由“隐式绑定”规则决定的,即函数的调用者是谁,this 就指向谁。

  4. 构造函数调用
    在构造函数中,this 通常指向由构造函数创建的新对象。例如:

    function Student(name, age) {
        this.name = name;
        this.age = age;
    }
    var stu1 = new Student('张三', 18);
    console.log(stu1.name); // 输出: 张三
    

    在这里插入图片描述

    当使用 new 关键字调用构造函数 Student 时,this 指向新创建的对象 stu1,因此可以通过 this.namethis.age 为该对象设置属性。构造函数的设计理念是通过“新绑定”将属性和方法绑定到新对象上,从而实现对象实例的封装和隔离。

  5. 箭头函数
    箭头函数中的 this 是词法绑定的,即它会继承定义时的上下文中的 this,而不是调用时的上下文。例如:

    function outer() {
        this.value = 42;
        const inner = () => {
            console.log(this.value);
        };
        inner();
    }
    outer(); // 输出: 42
    

    在这里插入图片描述 在上述代码中,inner 是一个箭头函数,它的 this 绑定了定义时的上下文,即 outer 函数的上下文。因此,当调用 inner() 时,this.value 输出为 42。这种“词法绑定”特性使得箭头函数在回调函数中避免了常见的 this 迷失问题,使代码更加简洁明了。


this 在全局环境中为什么指向 window

在 JavaScript 中,window 对象不仅代表浏览器窗口,同时也是浏览器环境中的全局对象。任何在全局作用域中声明的变量和函数,都会被作为属性或方法附加到 window 对象上。例如:

var x = 10;
console.log(window.x); // 输出: 10

在这里插入图片描述

在这段代码中,全局变量 x 实际上成为了 window 对象的一个属性,因此可以通过 window.x 来访问其值。在浏览器环境下,全局作用域中的所有使用 var 声明的变量都会自动成为 window 对象的属性。这种行为的目的是为了提供全局访问的便利性,尽管这种设计在大型项目中会带来命名冲突等问题。

然而,使用 letconst 声明的全局变量则不会成为 window 的属性,这是 ES6 中对作用域的改进,使得全局变量不会意外污染全局对象:

let y = 20;
console.log(window.y); // 输出: undefined

在这里插入图片描述

在这里,变量 y 并没有成为 window 对象的属性,因为它是通过 let 声明的。这种行为能够更好地实现变量的局部化,减少对全局对象的污染,增强代码的可维护性和模块化。


💯构造函数中的 this

构造函数中的 this 通常指向新创建的对象,例如:

function Student(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.speak = function () {
        console.log('我要学习,学习使我快乐,我叫 ' + this.name);
    };
}

var stu3 = new Student('张三', 18, '男');
console.log(stu3 instanceof Student); // 输出: true
console.log(stu3 instanceof Object); // 输出: true

在这里插入图片描述


this 的指向

在构造函数 Student 中,this 被绑定到通过 new 创建的新对象。在执行 new Student('张三', 18, '男') 时,JavaScript 会隐式地创建一个新的空对象,并将 this 指向这个新对象。因此,在构造函数中对 this 的所有引用,实际上都是对这个新对象的引用,使得该对象得以拥有 name, agesex 等属性。

构造函数的核心作用是实现对象的封装,每次调用构造函数时都会创建一个新的对象实例,其属性和方法都是独立的。通过构造函数来创建对象,可以有效地实现代码的复用和逻辑的封装,符合面向对象编程的基本原则。
在这里插入图片描述


instanceof 检查

在 JavaScript 中,instanceof 操作符用于判断一个对象是否是由某个构造函数创建的实例。以下是一个示例:

console.log(stu3 instanceof Student); // 输出: true
console.log(stu3 instanceof Object);  // 输出: true

在这里插入图片描述
stu3 instanceof Student 返回 true,因为 stu3 是由 Student 构造函数创建的实例。同样,stu3 instanceof Object 也返回 true,因为在 JavaScript 中,所有对象都是 Object 的实例。这种继承关系的验证使得 instanceof 成为判断对象原型链归属的重要工具,尤其在面向对象编程的场景中极为有用。


💯思路总结:为何全局变量是 window 的属性?

在这里插入图片描述
JavaScript 的初衷是为了在浏览器环境中执行脚本,因此,window 对象被设计为全局作用域的宿主对象。所有在全局范围内声明的变量、函数等,都会作为 window 对象的属性和方法存在,以便于在整个脚本中便捷地访问和使用。这种设计对于编写简单的脚本非常直观,但也引发了变量污染和命名冲突等问题。

随着 JavaScript 的发展,语言本身不断演进,尤其是引入了 letconst 关键字,这些改进使得开发者能够避免将所有全局变量都暴露到 window 对象,从而降低全局作用域污染的风险。此外,模块化编程的普及也为代码的封装性和复用性提供了更好的解决方案。

理解 this 的工作原理是编写健壮 JavaScript 代码的基础。不同的函数调用方式决定了 this 的不同指向,开发者在编写代码时必须时刻关注调用的上下文,避免因误解 this 而引入潜在的 bug。在编写复杂应用程序时,错误使用 this 是导致代码混乱和难以调试的主要原因之一,因此深入掌握 this 的指向规则是 JavaScript 开发中的关键技能。


严格模式下的区别

值得注意的是,在严格模式("use strict")下,this 的行为会有所不同。例如,在严格模式下,直接调用一个函数,this 将是 undefined,而不是全局对象 window

"use strict";
function f1() {
    console.log(this); // 严格模式下,输出: undefined
}
f1();

在这里插入图片描述

严格模式的引入是为了帮助开发者避免一些潜在的错误,通过引入更加严格的规则来提高代码的健壮性和安全性。在严格模式下,this 的指向规则变得更加明确,不会再默认指向全局对象,减少了许多常见的错误。


💯小结

  • 在这里插入图片描述
    JavaScript 中的 this 是一个功能强大但同时复杂的特性,其值取决于函数的调用方式和上下文。在全局作用域中,this 通常指向全局对象 window,因此全局变量也会成为 window 的属性。理解这些细节对于编写健壮且可维护的 JavaScript 代码至关重要。
    为了更好地理解和使用 this,开发者需要深入掌握各种调用上下文的规则,并学会如何在不同场景中使用 this 来避免陷阱。同时,通过利用严格模式和模块化来减少潜在的错误,可以显著提高代码的质量和可维护性。掌握 this 的使用对于每个追求精通 JavaScript 的开发者而言,都是一项必不可少的技能。
    希望本文能够帮助你深入理解 JavaScript 中 this 的工作原理,特别是它在不同上下文中的指向,以及全局变量与 window 对象的关系。如果在编码过程中遇到 this 的问题,可以回顾本文的内容,帮助自己厘清思路。此外,建议尽可能使用严格模式和模块化来提升代码的健壮性和可维护性,避免全局变量的滥用,从而编写出高质量的 JavaScript 应用程序。

在这里插入图片描述



http://www.kler.cn/a/420803.html

相关文章:

  • 故障诊断 | Transformer-LSTM组合模型的故障诊断(Matlab)
  • 使用 LLaMA-Factory 微调
  • idea 自动导包,并且禁止自动导 *(java.io.*)
  • C# 集合(Collection)
  • uniapp实现加密Token并在每次请求前动态更新(vue、微信小程序、原生js也通用!)
  • 【ONE·基础算法 || 动态规划(三)】
  • diffusion model: prompt-to-prompt 深度剖析
  • 设计模式:15、生成器模式
  • TinyXML2的一些用法
  • dpwwn02靶场
  • 探讨播客的生态系统
  • 第 41 章 - Go语言 软件工程原则
  • 目标检测标注图像
  • 目标检测模型和图像分割模型
  • ES6 对象扩展全解析:属性简写、表达式、super 关键字等的深度应用
  • Qt5语法的connect指定多个重载信号槽函数中的具体某一个
  • Day6 洛谷 1426+1425+1424+1423+1422+1614+1634+1639
  • 基于Springboot + Vue开发的美食探索及分享平台
  • Maxwell的入门实战
  • java基础概念46-数据结构1
  • Rust循环引用与多线程并发
  • 浏览器中输入一个URL后,按下回车后发生了什么
  • Truffle和Remix简介
  • 基础原型链污染
  • K8S资源之secret资源
  • 基于Java Springboot传统戏曲推广微信小程序