浅谈一下对于 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
其它注意点:
- 要注意开始提到的 在严格模式下可以是任意值的概念:
在非严格模式下使用
call
和apply
时,如果用作this
的值不是对象,则会被尝试转换为对象。null
和undefined
被转换为全局对象。原始值如7
或'foo'
会使用相应构造函数转换为对象。因此7
会被转换为new Number(7)
生成的对象,字符串'foo'
会转换为new String('foo')
生成的对象。
- 在箭头函数中,
this
与封闭词法环境的this
保持一致。在全局代码中,它将被设置为全局对象。
如果将
this
传递给call
、bind
、或者apply
来调用箭头函数,它将被忽略。不过你仍然可以为调用添加参数,不过第一个参数(thisArg
)应该设置为null
。
如今这里荒草丛生没有了鲜花,好在曾今拥有你们的春秋和冬夏。