浅谈一下对于 js 中的 this 的理解

浅谈一下对于 js 中的 this 的理解




对于 this 值的定义:

简单来说 this 是一个对象,这个对象具体的值是什么,取决于运行时的环境,即代码执行时的环境。

MDN:

当前执行上下文( global 、 function 或 eval )的一个属性,在非严格模式下,总是指向一个 对象 ,在严格模式下可以是 任意值

解释:

  • global 是指全局对象,例如浏览器环境下的 window ,node 环境下的 global
  • eval 是指的 eval() 函数,它可以将传入的字符串当作 js 代码执行。(尽量不要使用,执行速度更慢且容易造成安全问题)

稍微简单的理解是:

在全局环境下,this 指全局对象;在函数中,如果该函数是对象(object)或者类(class)的属性,this 指代当前对象或者类,如果是直接声明并执行的函数,则是全局对象(非严格模式)。以上的总结在大部分场景下是正确的。



具体到代码环境下 this 所代表的值:

以下列举一些常见的代码片段:

注释 // 后面会说明 this 指代的值,以方便理解,以下代码都是在非任意 {} 包裹的代码块中实现

console.log(this); // window
function test() {
  console.log(this); // window
}
test();
setTimeout(function () {
  console.log("---");
  console.log(this); // window
  console.log("---");
}, 100);
"use strict"; // 严格模式
function test2() {
  console.log(this); //undefined
}
test2();
const person = {
  id: 1,
  name: "tom",
  do: function () {
    console.log(this.id); // 这里的 this 就是指代 person 这个对象
    console.log("do something about");
  },
};
class food {
  constructor(name) {
    this.name = name; // 这里的 this 指 food 这个类
  }
}
class cookedFood extends food {
  constructor(name, type) {
    // console.log(this); // 会报错,子类必须在调用 super 方法后才能使用 this
    super(name);
    this.type = type; // 这里的 this 指 cookedFood 这个类
  }
}

new cookedFood("鱼", "红烧");
const obj = { a: 1 };
var a = 0;
function whatThis() {
  return this.a;
}
whatThis(); // 0  this 指 window
whatThis.call(obj); // 1  this 指 obj
whatThis.apply(obj); // 1  this 指 obj

其它注意点:

  • 要注意开始提到的 在严格模式下可以是任意值的概念

在非严格模式下使用 callapply 时,如果用作 this 的值不是对象,则会被尝试转换为对象。nullundefined 被转换为全局对象。原始值如 7'foo' 会使用相应构造函数转换为对象。因此 7 会被转换为 new Number(7) 生成的对象,字符串 'foo' 会转换为 new String('foo') 生成的对象。

  • 在箭头函数中,this与封闭词法环境的this保持一致。在全局代码中,它将被设置为全局对象。

如果将this传递给callbind、或者apply来调用箭头函数,它将被忽略。不过你仍然可以为调用添加参数,不过第一个参数(thisArg)应该设置为null

posted @ 2023-05-05 22:01  镜暮  阅读(91)  评论(0编辑  收藏  举报