5分钟懂一个前端知识点系列之this关键字

前言

本人在学习this和原型(特别是this指向)的时候遇到了些许困惑,今天跟大家详细解释一下我在学习路上对this和原型的了解。难点先来攻克,今天先来讲讲this。这里统一声明不讨论严格模式下面的使用,因为我也不了解不能误导大家!

this

this 关键字在JavaScript中主要用于指代当前函数执行时的上下文对象,即函数内部的一个特殊变量,它指向函数调用时所属的对象。如果不太清楚函数上下文对象的可以看我的5分钟系列的其他文章,里面有讲解函数执行的上下文对象是个啥,存储的是什么内容,这里就不过多描述。

this 关键字是一个非常重要且有时可能引起混淆的概念。它的值取决于函数调用的上下文 ,即函数是如何被调用的,而不是函数在哪里被定义

普通函数this指向
  • 普通函数是不需要this对象的,因为仅仅只是使用函数并不需要知道函数执行的所属对象。所以一个普通函数是没有特定的this指向的,默认指向window全局对象
对象内部的this指向
  • 一个对象内部的this指向一般都是对象本身,当然也有例外
    看下面这段代码

      function Person(){
          function printThis(){
              console.log(this);
          }
      }
      var p1 =new Person().printThis;
      p1();
    

这里输出打印的this指向的是全局对象,因为这里的printThis函数是被当作一个普通函数调用了。普通函数调用this就是默认指向全局。

如何判断一个函数会被当成普通函数

如果一个函数不是作为某个对象的方法被调用,也没有使用.call(), .apply(), 或 .bind() 方法来改变this的绑定(这个可以暂时先不管),那么它被视为直接调用当作一个普通函数。

而上段代码创建了一个Person的实例,并尝试访问其printThis方法,但随后立即丢弃了新创建的实例,只保留了printThis函数的引用。当执行p1()时,printThis函数是以独立函数的形式被调用的,而非作为某个对象的方法调用。所以这里的printThis也被当做了普通函数。

如果回调函数是在全局上下文中定义的或者在非严格模式下被调用,且没有通过对象方法调用,那么this通常指向全局对象

箭头函数this指向

箭头函数不绑定自己的this,它会捕获其所在上下文的this值作为自己的this值,也就是词法作用域下的this

这意味着在箭头函数中,this的值是定义时所在的上下文决定的,而非调用时的上下文。这对于避免常规函数中常见的this混乱问题非常有帮助,尤其是在处理异步代码、回调函数或者在类的方法中。下面是一段实例代码

const obj = {
    normalFunc: function() {
        setTimeout(function() {
            console.log(this); // 这里的this通常指向全局对象(非严格模式)
        }, 1000);
    },
    arrowFunc: function() {
        setTimeout(() => {
            console.log(this); // 这里的this指向obj对象,因为箭头函数没有自己的this,它继承了外层的this
        }, 1000);
    }
};

obj.normalFunc(); // 输出可能不是obj
obj.arrowFunc(); // 输出obj

测试

下面是有关的几道题目可以尝试做做。这里的答案都是在浏览器上执行,而非nodeJS因为两者全局对象有所不同。

1 复制代码
function showName() { console.log(this.name); }// 这里的this指向哪里?输出什么?
var name = "全局"; 
showName(); 

答案解析 : this指向全局对象(浏览器中是window,Node.js中是global)。

2 复制代码
const obj = {
  name: "Object",
  showName: function() {
    console.log(this.name);// 这里this指向什么?输出什么?
  }
};

obj.showName(); 

答案解析 : 当函数作为对象的一个方法被调用时,this指向该对象。因此,这里this指向obj

3 复制代码
function Person(name) {
  this.name = name;
  setTimeout(function() {
    console.log(this.name); // 这里this指向什么?输出什么?
  }, 1000);
}

const person = new Person("Alice"); 

答案解析 : 在setTimeout的回调函数中,如果没有特别处理,this通常会指向全局对象(非严格模式下),因为它是作为全局函数调用的。因此,这里的this.name可能不是预期的"Alice",而是全局对象的属性。但是,题目问的是new Person("Alice")中的this,这里this指向新创建的Person实例,即指向新创建的person对象。

4 复制代码
function Person(name) { this.name = name; } 
Person.prototype.printName = function() { console.log(this.name); }; // 这里的this指向哪里?
const person = new Person("Bob"); 
person.printName(); //输出什么?

答案解析 : 当通过实例调用原型链上的方法时,this指向该实例。因此,person.printName()中的this指向person实例,输出是"Bob"。

相关推荐
m0_748247551 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
m0_748255022 小时前
前端常用算法集合
前端·算法
真的很上进2 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203982 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
NiNg_1_2343 小时前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
如若1233 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~4 小时前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语4 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport4 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg4 小时前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全