node.js 動(dòng)態(tài)執(zhí)行腳本
node.js最近新增了虛擬機(jī)模塊,其實(shí)也不能說(shuō)是新增的,只是把一些內(nèi)部接口暴露出來(lái)罷了,從2.x就有了。我們可以從node / src / node.js看到這些代碼:
var Script = process.binding('evals').NodeScript;
var runInThisContext = Script.runInThisContext;
NativeModule.wrap = function(script) {
return NativeModule.wrapper[0] + script + NativeModule.wrapper[1];
};
NativeModule.wrapper = [
'(function (exports, require, module, __filename, __dirname) { ',
'\n});'
];
NativeModule.prototype.compile = function() {
var source = NativeModule.getSource(this.id);
source = NativeModule.wrap(source);
var fn = runInThisContext(source, this.filename, true);
fn(this.exports, NativeModule.require, this, this.filename);
this.loaded = true;
};
其中的Script對(duì)象,就與require('vm')返回的對(duì)象很相似,而實(shí)質(zhì)上,vm模塊就是對(duì)Script對(duì)象的封裝。
var Script = process.binding('evals').NodeScript;
console.log(Script)
/**
{ [Function: NodeScript]
createContext: [Function],
runInContext: [Function],
runInThisContext: [Function],
runInNewContext: [Function] }
*/
console.log(require('vm'))
{ Script:
{ [Function: NodeScript]
createContext: [Function],
runInContext: [Function],
runInThisContext: [Function],
runInNewContext: [Function] },
createScript: [Function],
createContext: [Function],
runInContext: [Function],
runInThisContext: [Function],
runInNewContext: [Function] }
其中,runInThisContext 相當(dāng)于一個(gè)全新的環(huán)境中執(zhí)行代碼,不會(huì)影響當(dāng)前作用域的對(duì)象。而runInNewContext與runInContext則能指定是上下文對(duì)象,區(qū)別是一個(gè)普通對(duì)象或一個(gè)context對(duì)象。換言之,runInNewContext與runInContext能局部影響當(dāng)前作用域的對(duì)象。要與當(dāng)前環(huán)境完全進(jìn)行交互的話,就需要用到危險(xiǎn)的eval。在node.js自帶的加載體系中,顯然沒(méi)有這樣的勇氣,使用的是runInThisContext。并且在這之前做了許多工作,如把用戶的JS文件里面的內(nèi)容再包一層( NativeModule.wrap),還有其他凌散操作,加之是同步操作,實(shí)際上是一種效率很糟的加載方式。唯一的好處是,使用了同步,讓代碼編寫起來(lái)簡(jiǎn)單多了。
在github中,已有人對(duì)這幾種動(dòng)態(tài)執(zhí)行腳本的方法進(jìn)行性能比較:
var vm = require('vm'),
code = 'var square = n * n;',
fn = new Function('n', code),
script = vm.createScript(code),
sandbox;
n = 5;
sandbox = { n: n };
benchmark = function(title, funk) {
var end, i, start;
start = new Date;
for (i = 0; i < 5000; i++) {
funk();
}
end = new Date;
console.log(title + ': ' + (end - start) + 'ms');
}
var ctx = vm.createContext(sandbox);
benchmark('vm.runInThisContext', function() { vm.runInThisContext(code); });
benchmark('vm.runInNewContext', function() { vm.runInNewContext(code, sandbox); });
benchmark('script.runInThisContext', function() { script.runInThisContext(); });
benchmark('script.runInNewContext', function() { script.runInNewContext(sandbox); });
benchmark('script.runInContext', function() { script.runInContext(ctx); });
benchmark('fn', function() { fn(n); });
/**
vm.runInThisContext: 212ms
vm.runInNewContext: 2222ms
script.runInThisContext: 6ms
script.runInNewContext: 1876ms
script.runInContext: 44ms
fn: 0ms
*/
由此可見,還是v8自帶的方法Function完勝!
以上就是本文的全部?jī)?nèi)容,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Selenium執(zhí)行JavaScript腳本的方法示例
- Selenium執(zhí)行Javascript腳本參數(shù)及返回值過(guò)程詳解
- js腳本中執(zhí)行java后臺(tái)代碼方法解析
- Java執(zhí)行JS腳本工具
- JS腳本加載后執(zhí)行相應(yīng)回調(diào)函數(shù)的操作方法
- Angularjs通過(guò)指令監(jiān)聽ng-repeat渲染完成后執(zhí)行腳本的方法
- JS動(dòng)態(tài)加載腳本并執(zhí)行回調(diào)操作
- 瀏覽器環(huán)境下JavaScript腳本加載與執(zhí)行探析之動(dòng)態(tài)腳本與Ajax腳本注入
- 瀏覽器環(huán)境下JavaScript腳本加載與執(zhí)行探析之defer與async特性
- 探析瀏覽器執(zhí)行JavaScript腳本加載與代碼執(zhí)行順序
- 詳解javascript腳本何時(shí)會(huì)被執(zhí)行
相關(guān)文章
nodejs和php實(shí)現(xiàn)圖片訪問(wèn)實(shí)時(shí)處理
這篇文章主要為大家詳細(xì)介紹了nodejs和php分別實(shí)現(xiàn)圖片訪問(wèn)實(shí)時(shí)處理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
mongoose設(shè)置unique不生效問(wèn)題的解決及如何移除unique的限制
這篇文章主要給大家介紹了關(guān)于mongoose數(shù)據(jù)庫(kù)設(shè)置unique不生效問(wèn)題的解決方法,以及Mongoose如何移除unique限制的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11
解決使用node命令提示:'node'不是內(nèi)部或外部命令,也不是可運(yùn)行的程序
最近在工作中遇到了個(gè)常見的問(wèn)題,分享給大家,這篇文章主要給大家介紹了關(guān)于如何解決使用node命令提示:'node'不是內(nèi)部或外部命令,也不是可運(yùn)行的程序的相關(guān)資料,需要的朋友可以參考下2023-02-02
基于Node的Axure文件在線預(yù)覽的實(shí)現(xiàn)代碼
這篇文章主要介紹了基于Node的Axure文件在線預(yù)覽的實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
服務(wù)端nodejs抓取jsonp接口數(shù)據(jù)實(shí)現(xiàn)示例
這篇文章主要為大家介紹了服務(wù)端nodejs抓取jsonp接口數(shù)據(jù)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
autojs的nodejs打包成品app經(jīng)驗(yàn)分享
這篇文章主要為大家介紹了autojs的nodejs打包成品app經(jīng)驗(yàn)分享,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01

