Node 中的 this

探究全局中的this

首先看一个例子

console.log(this) // {}
console.log(module) // Module {}
console.log(this === module) // false
console.log(this === global) // false
this.a = 0
console.log(this.a) // 0
console.log(global.a) // undefined
console.log(module.a) // undefined

全局中的this默认是一个空对象。并且在全局中this与global对象没有任何的关系,那么全局中的this究竟指向的是谁?

函数中的this

function fn(){
  this.num = 10;
}
fn();
console.log(this); {}
console.log(this.num); undefined
console.log(global.num); 10

在函数中this指向的是global对象,和全局中的this不是同一个对象,简单来说,你在函数中通过this定义的变量就是相当于给global添加了一个属性,此时与全局中的this已经没有关系了。

再看一个内部函数的例子

function fn(){
  function fn2(){
    this.age = 18
  }
  fn2();
  console.log(this) // global
  console.log(this.age) // 18
  console.log(global.age) // 18
}
fn()

这个例子可以很好的说明,在函数中this指向的是global。

构造函数中的this

function Fn(){
  this.num = 20
}
var fn = new Fn()
console.log(fn.num) // 20
console.log(global.num) // undefined

这没什么疑问,构造函数的this指向被创建的对象本身。

再谈全局this

实际上,一个js文件就是一个模块,使用module.exports方法可以暴露模块中的一些方法与属性,全局的this指向的是module.exports。

在一个模块文件中,可以省略module,因此module.exports === exports

this.num = 10
console.log(module.exports) // {num:10}
console.log(module.exports.num) // 10
console.log(this === module.exports) // true
console.log(module.exports === exports) // true
console.log(this === exports) // true

鉴于此,完全可以省略书写 module.exports ,直接将需要暴露的方法或属性附加到 this 即可。

test1.js

this.num = 10

test.js

var a = require('./test1.js')
console.log(a) // {num: 10}

模块详解

事实上,在定义一个模块的时候,运行的时候虚拟机会给当前模块加一层壳,以便与外部环境分离。

比如,在 test.js 中有以下代码:

var a = 12
exports.a = a

最后运行的时候会默认套上一层壳,相当于在一个沙箱中运行。如下:

(function (require, exports, module){
	var a = 12
	exports.a = a
})();

所以,在模块中定义的变量不存在全局变量。

MIT Licensed | Copyright © 2018-present 滇ICP备16006294号

Design by Quanzaiyu | Power by VuePress