this 变量
Node 应用的顶层变量是global,对应浏览器的window变量。
顶层的 this
在 REPL 环境,顶层的this就指向global。
顶层变量是global和this的属性。
上面代码中,foo是一个顶层变量,自动生成了this.foo和global.foo两个属性。
在模块环境,顶层的this指向当前模块,即module.exports,默认是一个空对象,与global不是同一个对象。
模块内部的顶层变量,不会自动成为global和this的属性。
上面代码中,顶层变量foo并不会生成this.foo和global.foo两个属性。这是因为foo是模块内部的变量,不是全局有效,因此不是global的属性,而this是当前的模块对象,this.foo代表模块实例的属性,这跟变量foo是两回事情。
另外,如果声明变量的时候,不使用var命令,而是直接赋值,那么该变量在 REPL 环境下将成为global和this的属性,在模块环境将只成为 global 的属性。
// REPL 环境
> foo = "bar";
> global.foo
bar
> this.foo
bar
// 模块环境
foo = "bar";
console.log(this.foo); // undefined
console.log(global.foo); // bar
函数内部的 this
直接执行一个函数(不使用new命令),函数内部的this指向global,REPL 环境和模块环境都是如此。
foo = "bar";
function testThis () {
this.foo = "foo";
}
console.log(global.foo); // bar
testThis();
console.log(global.foo); // foo
如果是严格模式,函数内部的this返回undefined。
foo = "bar";
function testThis() {
"use strict";
this.foo = "foo";
}
console.log(this.foo); // "bar"
testThis(); // TypeError: Cannot set property 'foo' of undefined
如果使用new命令调用某个函数,该函数就变成了构造函数,函数内部的this指向新建的实例对象。