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 相关文章推荐
使用JavaScript switch case 另类写法
Mar 14 Javascript
JS 精确统计网站访问量的实例代码
Jul 05 Javascript
jquery在项目中做复选框时遇到的一些问题笔记
Nov 17 Javascript
实例讲解JQuery中this和$(this)区别
Dec 08 Javascript
jQuery判断元素是否显示 是否隐藏的简单实现代码
May 19 Javascript
jquery 点击元素后,滚动条滚动至该元素位置的方法
Aug 05 Javascript
jQuery替换节点用法示例(使用replaceWith方法)
Sep 08 Javascript
JS匿名函数类生成方式实例分析
Nov 26 Javascript
Javascript blur与click冲突解决办法
Jan 09 Javascript
JS实现向iframe中表单传值的方法
Mar 24 Javascript
JavaScript数据结构之优先队列与循环队列实例详解
Oct 27 Javascript
Vue2 配置 Axios api 接口调用文件的方法
Nov 13 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
隐藏X-Space个人空间下方版权方法隐藏X-Space个人空间标题隐藏X-Space个人空间管理版权方法
2007/02/22 PHP
自制轻量级仿jQuery.boxy对话框插件代码
2010/10/26 Javascript
jQuery 淡出一个图像到另一个图像的实现代码
2013/06/12 Javascript
JS验证邮箱格式是否正确的代码
2013/12/05 Javascript
JS hashMap实例详解
2016/05/26 Javascript
从零开始学习Node.js系列教程四:多页面实现的数学运算示例
2017/04/13 Javascript
react.js 父子组件数据绑定实时通讯的示例代码
2017/09/25 Javascript
vue-cli 自定义指令directive 添加验证滑块示例
2017/10/19 Javascript
vue+iview+less 实现换肤功能
2018/08/17 Javascript
详解如何在Angular优雅编写HTTP请求
2018/12/05 Javascript
使用element-ui table expand展开行实现手风琴效果
2019/03/15 Javascript
微信小程序监听用户登录事件的实现方法
2019/11/11 Javascript
JavaScript undefined及null区别实例解析
2020/07/21 Javascript
Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)
2020/08/28 Javascript
[03:38]TI4西雅图DOTA2前线报道 71专访
2014/07/08 DOTA
Python类的专用方法实例分析
2015/01/09 Python
Python实现过滤单个Android程序日志脚本分享
2015/01/16 Python
python实现的简单猜数字游戏
2015/04/04 Python
在服务器端实现无间断部署Python应用的教程
2015/04/16 Python
Python cookbook(数据结构与算法)将名称映射到序列元素中的方法
2018/03/22 Python
Python基于Logistic回归建模计算某银行在降低贷款拖欠率的数据示例
2019/01/23 Python
详解小白之KMP算法及python实现
2019/04/04 Python
python函数enumerate,operator和Counter使用技巧实例小结
2020/02/22 Python
学习Python需要哪些工具
2020/09/04 Python
python自动化发送邮件实例讲解
2021/01/04 Python
Python3利用scapy局域网实现自动多线程arp扫描功能
2021/01/21 Python
在html5的Canvas上绘制椭圆的几种方法总结
2013/01/07 HTML / CSS
德国柯吉澳趣味家居:Koziol
2017/08/24 全球购物
最经典的商业地产项目广告词
2014/03/13 职场文书
纪检干部个人对照检查材料
2014/09/23 职场文书
老兵退伍标语
2014/10/07 职场文书
党的群众路线教育实践活动整改落实情况报告
2014/10/28 职场文书
平遥古城导游词
2015/02/03 职场文书
医护人员继续教育学习心得体会
2016/01/19 职场文书
如何用六步教会你使用python爬虫爬取数据
2022/04/06 Python
Vite + React从零开始搭建一个开源组件库
2022/06/25 Javascript