💡JS-函数中的this是什么?不同环境可不一样

244 阅读3分钟

函数中的 this 值是什么?不同环境,不同模式,不同函数内,它的值是不一样的。

我们一个一个看看:

浏览器环境

非严格模式

function Test() {
	console.log("test", this);
}

const Test2 = () => {
	console.log("test2", this);
};



Test();

Test2();

代码的目的是看看,两个不同的函数,如果都是用直接调用的方法执行,其中的 this 是什么值?

那上面的代码,在浏览器中运行结果是什么?

显示,两次输出都是 window 对象

为什么?

在浏览器中,如果是直接调用普通的 function 函数,那么 function 函数中的 this 指向 window 对象。对于箭头函数来说,其中的 this 并不是由调用方式决定的,而是由其声明的环境决定的。其中的 this 的值继承自父级作用域。而全局作用域中,this 的值也是 window 对象

严格模式

那同样是浏览器环境,如果是严格模式的话,上面代码的执行结果是什么呢?

在代码的眼前,加上'use strict',就可以开启严格模式了

严格模式下,箭头函数的打印结果还是一样的,但对于 function 函数的打印结果不同。

ECMA 组织规定,这时候 function 函数,如果是直接调用,那么其中的 this 不再指向 window 这个全局对象了,而是 undefined

node 环境

非严格模式

好,浏览器环境讲完了,下面看看 node 环境。先在非严格模式下执行:

上面是 node 环境下的执行结果。其中 function 函数和箭头函数的输出是不一样的。function 函数中的 this 指向全局对象 global。而箭头函数中 this 是一个空对象!

下面改改代码,让 this 的指向更清楚:

function Test() {
	console.log("test", this.name);
}

const Test2 = () => {
	console.log("test2", this.name);
};

global.name = "test zenos";
exports.name = "test2 zenos";

Test();
Test2();

在执行两个函数之前,分别给 global 对象和 exports 对象添加了 name 属性。函数内容的 this 打印也改成了只打印 this 中的 name。

执行结果:

从结果可以看出,function 函数中的 this 指向全局对象 global。而箭头函数中 this 指向 exports 对象!

严格模式

那么,同样是 node 环境,严格模式下会有什么变化吗?

"use strict";
function Test() {
  // 这里是this
	console.log("test", this);
}

const Test2 = () => {
	console.log("test2", this.name);
};

global.name = "test zenos";
console.log(global.name);

Test();

exports.name = "test2 zenos";

Test2();

上面修改一些代码,下面是打印结果:

可以看到在严格模式下,直接调用的 function 中的 this 是 undefined。不过全局对象 global 还是有的。全局环境中的 this 还是和 exports 一致。

四种环境

画板

总结

本篇文章比较短,主要讲了不同环境中的 this 的值是什么?

  • 浏览器环境,
    • 非严格模式
      • function:window
      • 箭头 function:window
    • 严格模式
      • function:undefined
      • 箭头 function:window
  • node 环境
    • 非严格模式
      • function:global
      • 箭头 function:exports
    • 严格模式
      • function:undefined
      • 箭头 function:exports

最后一个问题,为什么在 node 环境中,this 的值是 exports?理解需要一点模块化的知识,这个我们后面再讲