首页 > 编程语言 >JavaScript 中 this 关键字的作用和如何改变其上下文

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

时间:2023-01-21 14:45:24浏览次数:43  
标签:obj 函数 指向 JavaScript 42 value 关键字 printValue 上下文

一、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 指向,从而在不同的上下文中使用同一个函数。

标签:obj,函数,指向,JavaScript,42,value,关键字,printValue,上下文
From: https://www.cnblogs.com/yuzhihui/p/17063783.html

相关文章

  • javascript: node.js
     consthttp=require("http");http.createServer(function(request,response){response.writeHead(200,{'Content-type':'text/html'});response.end('<h1>......
  • 前端面试题 - javaScript系列
    Time:2023-01-2021:14:37ES6系列1.说说var、let、const之间的区别var、let、const三者区别可以围绕下面五点展开:变量提升暂时性死区块级作用域重复声明修......
  • javaScript
    JavaScript是一门流行脚本快速入门跟css一样,可以直接写在html中,放在script标签中alert可以弹出弹窗,内容用单引号引入的时候一定要成对出现,不能自闭和基本语法入门......
  • JavaScript 中断forEach循环
    1、使用Array.prototype.some()方法代替some()方法会在找到第一个符合条件的元素时停止循环。例如:letarray=[1,2,3,4,5];array.some(function(element,inde......
  • javaScript
    JavaScript是一门流行脚本快速入门跟css一样,可以直接写在html中,放在script标签中alert可以弹出弹窗,内容用单引号引入的时候一定要成对出现,不能自闭和 基本语法入门......
  • JavaScript 函数所能传递的最大参数
    取决于实现,取决于浏览器和操作系统标准没有规定(65535一般是有的)来源:https://stackoverflow.com/questions/22747068/is-there-a-max-number-of-arguments-javascript-fun......
  • Javascript数字精度丢失的问题,如何解决
    一、问题分析计算机存储以二进制的方式,而0.1在二进制中是无限循环的一个数字,所以会出现裁剪,精度丢失会出现,0.100000000000000002===0.1,0.200000000000000002===0.2......
  • javascript的防抖与节流
    一、节流一段时间内只能触发一次,如果这段时间内触发多次事件,只有第一次生效会触发回调函数,一段时间过后才能再次触发(一定时间内只执行第一次)应用场景1、鼠标连续不断......
  • JavaScript事件循环
    一、是什么先,JavaScript是一门单线程的语言,意味着同一时间内只能做一件事,但是这并不意味着单线程就是阻塞,而实现单线程非阻塞的方法就是事件循环在JavaScript中,所有的任......
  • javaScript数组的sort()方法
    javaScript数组的sort()方法:今天再学习javaScript的数组的Array.sort()方法时,遇到了一个很有意思的问题,这个方法,直接调用,其实并不会得到我们想要的排序,而是会以一种很机械......