node.js 动态执行脚本


Posted in Javascript onJune 02, 2016

node.js最近新增了虚拟机模块,其实也不能说是新增的,只是把一些内部接口暴露出来罢了,从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对象,就与require('vm')返回的对象很相似,而实质上,vm模块就是对Script对象的封装。

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 相当于一个全新的环境中执行代码,不会影响当前作用域的对象。而runInNewContext与runInContext则能指定是上下文对象,区别是一个普通对象或一个context对象。换言之,runInNewContext与runInContext能局部影响当前作用域的对象。要与当前环境完全进行交互的话,就需要用到危险的eval。在node.js自带的加载体系中,显然没有这样的勇气,使用的是runInThisContext。并且在这之前做了许多工作,如把用户的JS文件里面的内容再包一层( NativeModule.wrap),还有其他凌散操作,加之是同步操作,实际上是一种效率很糟的加载方式。唯一的好处是,使用了同步,让代码编写起来简单多了。

在github中,已有人对这几种动态执行脚本的方法进行性能比较:

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完胜!

以上就是本文的全部内容,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
document.onreadystatechange事件的用法分析
Oct 17 Javascript
js 异步处理进度条
Apr 01 Javascript
EasySlider 基于jQuery功能强大简单易用的滑动门插件
Jun 11 Javascript
js调用浏览器打印模块实现点击按钮触发自定义函数
Mar 21 Javascript
javascript包装对象实例分析
Mar 27 Javascript
javascript正则表达式中的replace方法详解
Apr 20 Javascript
解决vue 路由变化页面数据不刷新的问题
Mar 13 Javascript
微信网页登录逻辑与实现方法
Apr 29 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
May 27 Javascript
js图片无缝滚动插件使用详解
May 26 Javascript
微信小程序基于ColorUI构建皮皮虾短视频去水印组件
Nov 04 Javascript
深入浅析React中diff算法
May 19 Javascript
浅谈JavaScript 标准对象
Jun 02 #Javascript
JavaScript中的Array 对象(数组对象)
Jun 02 #Javascript
jQuery简单验证上传文件大小及类型的方法
Jun 02 #Javascript
JS脚本实现动态给标签控件添加事件的方法
Jun 02 #Javascript
JavaScript来实现打开链接页面的简单实例
Jun 02 #Javascript
JavaScript实现打开链接页面的方式汇总
Jun 02 #Javascript
JS读取XML文件数据并以table形式显示数据的方法(兼容IE与火狐)
Jun 02 #Javascript
You might like
PHP在Web开发领域的优势
2006/10/09 PHP
PHP实现异步调用方法研究与分享
2011/10/27 PHP
PHP编程中尝试程序并发的几种方式总结
2016/03/21 PHP
PHP目录操作实例总结
2016/09/27 PHP
jquery ajax执行后台方法
2010/03/18 Javascript
javascript 伪数组实现方法
2010/10/11 Javascript
整理的比较全的event对像在ie与firefox浏览器中的区别
2013/11/25 Javascript
代码触发js事件(click、change)示例应用
2013/12/13 Javascript
jquery处理json数据实例分析
2014/06/03 Javascript
JQuery中使用.each()遍历元素学习笔记
2014/11/08 Javascript
jQuery控制cookie过期时间的方法
2015/04/07 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
2016/07/25 Javascript
完全深入学习Bootstrap表单
2016/11/28 Javascript
webstorm添加vue.js支持的方法教程
2017/07/05 Javascript
jQuery+ajax实现动态添加表格tr td功能示例
2018/04/23 jQuery
Vue中使用vue-i18插件实现多语言切换功能
2018/04/25 Javascript
Nodejs实现多文件夹文件同步
2018/10/17 NodeJs
javascript使用substring实现的展开与收缩文字功能示例
2019/06/17 Javascript
JavaScript实现横版菜单栏
2020/03/17 Javascript
javascript 设计模式之享元模式原理与应用详解
2020/04/08 Javascript
[41:41]TFT vs Secret Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
python抓取网页内容示例分享
2014/02/24 Python
Python操作json数据的一个简单例子
2014/04/17 Python
Python+pyplot绘制带文本标注的柱状图方法
2019/07/08 Python
Python3 使用selenium插件爬取苏宁商家联系电话
2019/12/23 Python
python数据预处理方式 :数据降维
2020/02/24 Python
Python Selenium操作Cookie的实例方法
2021/02/28 Python
纯css3实现图片翻牌特效
2015/03/10 HTML / CSS
Html5移动端适配IphoneX等机型的方法
2019/06/25 HTML / CSS
护士自荐信
2013/10/25 职场文书
医药专业应届毕业生求职信范文
2014/01/01 职场文书
护士医德考评自我评价
2015/03/03 职场文书
企业财务管理制度范本
2015/08/04 职场文书
Python 中random 库的详细使用
2021/06/03 Python
适合后台管理系统开发的12个前端框架(小结)
2021/06/29 Javascript
HTML5页面打开微信小程序功能实现
2022/09/23 HTML / CSS