一、this 关键字的作用

JavaScript 中的 this 关键字引用了所在函数正在被调用时的对象。在不同的上下文中,this 的指向会发生变化。

在全局上下文中,this 指向全局对象(在浏览器中是 window 对象,在 Node.js 中是 global 对象)。

在函数中,this 指向调用该函数的对象。如果该函数是通过对象的方法调用的,那么 this 指向该对象;如果是通过函数调用的,那么 this 指向全局对象。

在箭头函数中,this 继承自父级作用域中的 this

在类的构造函数中,使用 new 关键字调用类时,this 指向新创建的对象。

例如:

class MyClass {
constructor() {
this.value = 42;
}
} let obj = new MyClass();
console.log(obj.value); // 42

类的实例方法中的 this 默认指向实例本身,类方法中的 this 默认指向类本身

例如:

class MyClass {
value = 42;
printValue() {
console.log(this.value);
}
static printValue() {
console.log(this.value);
}
} let obj = new MyClass();
obj.printValue(); // 42
MyClass.printValue(); // undefined

使用 Object.create 方法创建对象

使用 Object.create 方法创建是一种特殊的调用方式。在这种情况下,如果在对象的原型链上调用函数,则 this 指向该对象。

例如:

let baseObject = { value: 42 };
let obj = Object.create(baseObject); function printValue() {
console.log(this.value);
} printValue.call(obj); // 42

这种情况下, obj 的原型链上有 value 属性,所以调用 printValue() 方法时, this 指向 obj 对象。

在类中使用箭头函数

类中使用箭头函数定义的方法中的 this 指向是绑定的,它指向的是类的实例,而不是类本身。

例如:

class MyClass {
value = 42;
printValue = () => {
console.log(this.value);
}
}
let obj = new MyClass();
obj.printValue(); // 42

箭头函数的 this 是定义时的 this,而不是调用时的 this。因此,在类中使用箭头函数可以避免在方法中使用 bind 来绑定 this

在调用构造函数时,未使用 new 关键字

在这种情况下,this 指向全局对象。这种情况下不会创建新的对象,而是改变了全局对象的状态。

例如:

class MyClass {
constructor() {
this.value = 42;
}
} let obj = MyClass(); // without new keyword
console.log(obj); // undefined
console.log(value); // 42

因此,在使用构造函数创建对象时,需要确保使用 new 关键字来调用构造函数,否则可能会导致意外的结果。

在使用构造函数时特别需要注意使用 new 关键字来调用。

在对象的方法中使用箭头函数会导致 this 指向问题

例如:

let obj = {
value: 42,
printValue: () => {
console.log(this.value);
}
};
obj.printValue(); // undefined

这种情况下,在 obj 对象的 printValue 方法中使用了箭头函数,而箭头函数的 this 指向是定义时的 this,而不是调用时的 this。在这种情况下,因为箭头函数的 this 指向是定义时的 this,所以 this.value 指向的是 undefined,而不是 obj 对象中的 value。

解决这种问题可以使用箭头函数的父级作用域中的 this,或者使用普通函数来解决。

例如:

let obj = {
value: 42,
printValue: function(){
console.log(this.value);
}
};
obj.printValue(); // 42

或者

let obj = {
value: 42,
printValue: () => {
console.log(obj.value);
}
};
obj.printValue(); // 42

在对象的方法中使用箭头函数会导致 this 指向问题,需要特别注意。可以使用箭头函数的父级作用域中的 this 或者普通函数来解决。

总之,JavaScript 中的 this 关键字指向的上下文取决于函数的调用方式,需要根据不同的场景来选择合适的方式来改变 this 的指向。

二、如何改变 this 上下文

可以通过 call, apply, bind 方法来改变 this 的上下文。

callapply 方法允许您将函数的 this 指向指定的对象,并立即执行该函数。

call 方法的语法格式如下:

functionName.call(thisArg, arg1, arg2, ...);

apply 方法的语法格式如下:

functionName.apply(thisArg, [arg1, arg2, ...]);

bind 方法允许您将函数的 this 指向指定的对象,但不立即执行函数,而是返回一个新函数,可以在将来执行。

let newFunc = functionName.bind(thisArg, arg1, arg2, ...);

例如:

let obj = {value: 42};

function printValue() {
console.log(this.value);
} printValue.call(obj); // 42
printValue.apply(obj); // 42
let boundFunc = printValue.bind(obj);
boundFunc(); // 42

总之,通过使用 call, apply, bind 方法,可以改变函数中的 this 指向,从而在不同的上下文中使用同一个函数。

JavaScript 中 this 关键字的作用和如何改变其上下文的更多相关文章

  1. 深入解析Javascript中this关键字的使用

    深入解析Javascript中面向对象编程中的this关键字 在Javascript中this关键字代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.比如: function TestFun ...

  2. JavaScript中this关键字的使用比较

    JavaScript中this关键字的使用比较 this关键字在JavaScript中,用的不能说比较多,而是非常多.那么熟悉this关键字的各种用法则显得非常关键. this有时候就是我们经常说的上 ...

  3. 【Java_基础】Java中Native关键字的作用

    本篇博文转载与:Java中Native关键字的作用

  4. JavaScript中var关键字的使用详解

    作用 声明作用:如声明个变量. 语法 ? 1 var c = 1; 省略var 在javascript中,若省略var关键字而直接赋值,那么这个变量为全局变量,哪怕是在function里定义的. ? ...

  5. [No000069]Javascript中this关键字详解

    Quiz 请看下面的代码,最后alert出来的是什么呢?(chrome下按F12,选择Console直接复制粘贴运行) var name = "Bob"; var nameObj ...

  6. 大前端学习笔记整理【五】关于JavaScript中的关键字——this

    写在前面 工作有那么一段时间了,但是在工作中,发现自己的理论知识还是有所欠缺.特别是在javascript上,很多东西其实自己属于知道要用这个,但是不知道为什么要这么用...这种情况很是尴尬了,所以写 ...

  7. javascript中this关键字详解

    不管学习什么知识,习惯于把自己所学习的知识列成一个list,会有助于我们理清思路,是一个很好的学习方法.强烈推荐. 以下篇幅有点长,希望读者耐心阅读. 以下内容会分为如下部分: 1.涵义 1.1:th ...

  8. javascript中的关键字和保留字

    javascript中关键字的问题,将名称替换了下,确实就没有问题了.现在将它的关键字和保留字贴出来,便于日后查看和避免在次出现类似的问题. 1 关键字breakcasecatchcontinuede ...

  9. java中volatitle关键字的作用

    用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致 的情况.volatile就是用 ...

  10. java中static关键字的作用

    java中static关键字主要有两种作用: 第一:为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关. 第二,实现某个方法或属性与类而不是对象关联在一起 简单来说,在Java语言中,s ...

随机推荐

  1. docker swarm快速部署redis分布式集群

    环境准备 四台虚拟机 192.168.2.38(管理节点) 192.168.2.81(工作节点) 192.168.2.100(工作节点) 192.168.2.102(工作节点) 时间同步 每台机器都执 ...

  2. Python 多重继承时metaclass conflict问题解决与原理探究

    背景 最近有一个需求需要自定义一个多继承abc.ABC与django.contrib.admin.ModelAdmin两个父类的抽象子类,方便不同模块复用大部分代码,同时强制必须实现所有抽象方法,没想 ...

  3. 驱动开发:内核封装WSK网络通信接口

    本章LyShark将带大家学习如何在内核中使用标准的Socket套接字通信接口,我们都知道Windows应用层下可直接调用WinSocket来实现网络通信,但在内核模式下应用层API接口无法使用,内核 ...

  4. NC-日志配置及代码详解

    目录 一.日志文件输出说明 二.日志配置说明 2.1 配置文件路径 2.2 配置格式 2.2.1 参数说明 三.代码说明 四.自定义日志实例 实例1-新建日志类 实例2-直接在代码中使用日志输出 五. ...

  5. phpword 模板文件导出word到服务器 并浏览器下载

    模板文件填充 然后生成新文件 //调用PHPwordrequire_once(ROOTPATH . "inc/vendor/autoload.php"); $phpWord = n ...

  6. C温故补缺(五):main函数的参数

    main()的参数 main()函数的参数,用于在外部执行时传入参数,类似windows的bat脚本或linux的sh脚本.在bat脚本中传入参数,用%接收.sh脚本的参数用$接收. c语言编译成可执 ...

  7. java - - spring:定时任务

    转载:https://www.cnblogs.com/lishupeng/p/7680644.html 开启定时任务: <beans xmlns="http://www.springf ...

  8. goioc:一个使用 Go 写的简易的 ioc 框架

    目录 goioc 介绍 快速上手 接口介绍 使用 goioc 如何使用 生命周期 实例化 获取对象 结构体字段依赖注入 Dispose 接口 反射形式使用 goioc 如何使用 接口.结构体.结构体指 ...

  9. <十>关于菱形继承

    代码1 #include <iostream> using namespace std; class A{ public: A(int _a):ma(_a){ cout<<&q ...

  10. Golang反射获得变量类型和值

    1. 什么是反射 反射是程序在运行期间获取变量的类型和值.或者执行变量的方法的能力. Golang反射包中有两对非常重要的函数和类型,两个函数分别是: reflect.TypeOf 能获取类型信息re ...