/

了解nodeJS中的this

“This” in nodeJS

以下討論 nodeJS 中的 this,與 javascript 中的 this 不同,請不要搞混了。

function 外的 this

function 外的 this 指向 module.exports

1
console.log('outside: ', this) // {}
1
2
module.exports.bar = 3
console.log('outside: ', this) // outside: { bar: 3 }

切記!這個 this 並不是 global

function 中的 this

function 中的 this 才是指向 global

1
2
3
4
function foo(argument) {
console.log(this)
}
foo()

output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Object [global] {
DTRACE_NET_SERVER_CONNECTION: [Function],
DTRACE_NET_STREAM_END: [Function],
DTRACE_HTTP_SERVER_REQUEST: [Function],
DTRACE_HTTP_SERVER_RESPONSE: [Function],
DTRACE_HTTP_CLIENT_REQUEST: [Function],
DTRACE_HTTP_CLIENT_RESPONSE: [Function],
global: [Circular],
process:
process {
title: 'node',
version: 'v10.14.1',
versions:
{ http_parser: '2.8.0',
node: '10.14.1',
v8: '6.8.275.32-node.36',
...
...
...

如果我們確定 function 中的 this 指向 global,那麼可以透過以下例子在 global 新增屬性

1
2
3
4
5
function foo(argument) {
this.apple = 'A big apple'
}
foo()
console.log(global.apple) //A big apple

物件中的 this

再來,我們要討論物件中的 this,這邊就跟其他程式語言較為類似,物件中的 this 指向物件本身。

1
2
3
4
5
6
7
8
9
10
11
12
class Foo {
constructor() {
console.log(this)
}
}

function foo2() {
console.log(this)
}

new Foo() //Foo {}
new foo2() //foo2 {}

arrow function 中的 this

1
2
3
4
5
6
7
8
9
10
11
let obj = {
foo() {
console.log(this)
},
arr: () => console.log(this)


}

obj.foo() //{ foo: [Function: foo], arr: [Function: arr] }
obj.arr() //{}

要注意的是 arrow function 不會有自己的空間,即使在物件中也是。

這邊 arrow function 的 this 指向的是 module.exports (相同於 function 外的 this)

為何這麼複雜?

為什麼 nodeJS 的 this 要這樣設計?

其實跟作用域有關,在 nodeJS 中,每一個份 js 檔案都是一份 module。然而這樣的設計有利於區隔不同 module 之間的命名空間。


我們在 A 檔案下的 global 屬性,只要 B 引入 A 模組,就可以直接使用 A 檔案的 global 屬性。

A.js

1
2
3
global.bar = 3
bar2 = 5 // 直接宣告其實就是在 global 之下
var bar3 = 7 // 用 var 是在另外一塊作用域之中,只有該檔案看得到

B.js

1
2
3
4
5
6
require('./A')
console.log(global.bar) //3
//當然 我們也可以這樣使用 bar
console.log(bar) //3
console.log(bar2) //5
console.log(bar3) //ReferenceError: bar3 is not defined

由以上例子又可以知道,其實我們原本直接使用的那些 function,通通都在 global 之中

1
console.log(global.console.log === console.log) // true