nodejs vm 模塊淺析
Nodejs作用域
說(shuō)到作用域,我們就要說(shuō)一下Node中的作用域是怎么分配的(在Node中一般把作用域叫上下文)。
在Web端(瀏覽器),發(fā)揮作用的一般是JavaScript,學(xué)過(guò)JavaScript的師傅應(yīng)該都知道我們打開(kāi)瀏覽器的窗口是JavaScript中最大的對(duì)象window
,那么在服務(wù)端發(fā)揮作用的Node它的構(gòu)造和JavaScript不太一樣。
我們?cè)趯懸粋€(gè)Node項(xiàng)目時(shí)往往要在一個(gè)文件里ruquire其他的js文件,這些文件我們都給它們叫做“包”。每一個(gè)包都有一個(gè)自己的上下文,包之間的作用域是互相隔離不互通的,也就是說(shuō)就算我在y1.js中require了y2.js,那么我在y1.js中也無(wú)法直接調(diào)用y2.js中的變量和函數(shù)

這個(gè)時(shí)候就有人會(huì)問(wèn)左上角的global是什么?這里就要說(shuō)到Nodejs中的全局對(duì)象了。
剛才我們提到在JavaScript中window
是全局對(duì)象,瀏覽器其他所有的屬性都掛載在window
下,那么在服務(wù)端的Nodejs中和window
類似的全局對(duì)象叫做global
,Nodejs下其他的所有屬性和包都掛載在這個(gè)global對(duì)象下。在global下掛載了一些全局變量,我們?cè)谠L問(wèn)這些全局變量時(shí)不需要用global.xxx
的方式來(lái)訪問(wèn),直接用xxx
就可以調(diào)用這個(gè)變量。舉個(gè)例子,console
就是掛載在global下的一個(gè)全局變量,我們?cè)谟?code>console.log輸出時(shí)并不需要寫成global.console.log
在當(dāng)前global下創(chuàng)建一個(gè)作用域(sandbox),并將接收到的參數(shù)當(dāng)作代碼運(yùn)行。sandbox中可以訪問(wèn)到global中的屬性,但無(wú)法訪問(wèn)其他包中的屬性。
vm.createContext([sandbox])
: 在使用前需要先創(chuàng)建一個(gè)沙箱對(duì)象,再將沙箱對(duì)象傳給該方法(如果沒(méi)有則會(huì)生成一個(gè)空的沙箱對(duì)象),v8為這個(gè)沙箱對(duì)象在當(dāng)前global外再創(chuàng)建一個(gè)作用域,此時(shí)這個(gè)沙箱對(duì)象就是這個(gè)作用域的全局對(duì)象,沙箱內(nèi)部無(wú)法訪問(wèn)global中的屬性。vm.runInContext(code, contextifiedSandbox[, options])
:參數(shù)為要執(zhí)行的代碼和創(chuàng)建完作用域的沙箱對(duì)象,代碼會(huì)在傳入的沙箱對(duì)象的上下文中執(zhí)行,并且參數(shù)的值與沙箱內(nèi)的參數(shù)值相同。
vm.runInNewContext(code[, sandbox][, options])
: creatContext和runInContext的結(jié)合版,傳入要執(zhí)行的代碼和沙箱對(duì)象。vm.Script類
?vm.Script類型的實(shí)例包含若干預(yù)編譯的腳本,這些腳本能夠在特定的沙箱(或者上下文)中被運(yùn)行。new vm.Script(code, options)
:創(chuàng)建一個(gè)新的vm.Script對(duì)象只編譯代碼但不會(huì)執(zhí)行它。編譯過(guò)的vm.Script此后可以被多次執(zhí)行。值得注意的是,code是不綁定于任何全局對(duì)象的,相反,它僅僅綁定于每次執(zhí)行它的對(duì)象。
code:要被解析的JavaScript代碼