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 相关文章推荐
web前端开发也需要日志
Dec 09 Javascript
js关闭父窗口时关闭子窗口
Apr 01 Javascript
js 程序执行与顺序实现详解
May 13 Javascript
浅谈JavaScript函数节流
Dec 09 Javascript
jQuery过滤HTML标签并高亮显示关键字的方法
Aug 07 Javascript
JS获取当前使用的浏览器名字以及版本号实现方法
Aug 19 Javascript
js正则表达式注册页面表单验证
Oct 11 Javascript
angular.js+node.js实现下载图片处理详解
Mar 31 Javascript
微信小程序 MinUI组件库系列之badge徽章组件示例
Aug 20 Javascript
细述Javascript的加法运算符的具体使用
Oct 18 Javascript
js实现无刷新监听URL的变化示例代码详解
Jun 03 Javascript
Vue获取微博授权URL代码实例
Nov 04 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
完美实现GIF动画缩略图的php代码
2011/01/02 PHP
PHP实现下载远程图片保存到本地的方法
2017/06/19 PHP
JavaScript与DropDownList 区别分析
2010/01/01 Javascript
dwz 如何去掉ajaxloading具体代码
2013/05/22 Javascript
每天一篇javascript学习小结(String对象)
2015/11/18 Javascript
JS正则表达式比较常见用法
2016/01/26 Javascript
js中获取时间new Date()的全面介绍
2016/06/20 Javascript
javascript实现简单的可随机变色网页计算器示例
2016/12/30 Javascript
关于Angular2 + node接口调试的解决方案
2017/05/28 Javascript
详解如何实现Element树形控件Tree在懒加载模式下的动态更新
2019/04/25 Javascript
vue-video-player实现实时视频播放方式(监控设备-rtmp流)
2020/08/10 Javascript
使用JS实现鼠标放上图片进行放大离开实现缩小功能
2021/01/27 Javascript
[01:10]DOTA2次级职业联赛 - Fly战队宣传片
2014/12/01 DOTA
[04:59]2018DOTA2亚洲邀请赛 4.7 Mineski夺冠时刻
2018/04/09 DOTA
[01:28]国服启动器接入蒸汽平台操作流程视频
2021/03/11 DOTA
Python中的生成器和yield详细介绍
2015/01/09 Python
使用Python对IP进行转换的一些操作技巧小结
2015/11/09 Python
深入理解 Python 中的多线程 新手必看
2016/11/20 Python
python处理数据,存进hive表的方法
2018/07/04 Python
django如何连接已存在数据的数据库
2018/08/14 Python
在Python中获取两数相除的商和余数方法
2018/11/10 Python
python中数组和矩阵乘法及使用总结(推荐)
2019/05/18 Python
Python接口自动化判断元素原理解析
2020/02/24 Python
利用Python实现某OA系统的自动定位功能
2020/05/27 Python
python 爬虫基本使用——统计杭电oj题目正确率并排序
2020/10/26 Python
python温度转换华氏温度实现代码
2020/12/06 Python
HTML5样式控制示例代码
2013/11/27 HTML / CSS
Expedia丹麦:全球领先的旅游网站
2018/03/18 全球购物
计算机相关的自我评价
2014/01/15 职场文书
《少年王冕》教学反思
2014/04/11 职场文书
2015年餐厅服务员工作总结
2015/04/23 职场文书
简单的辞职信范文(2016最新版)
2015/05/12 职场文书
2015年出纳工作总结与计划
2015/05/18 职场文书
法律意见书范本
2015/06/04 职场文书
导游词之包公祠
2019/11/25 职场文书
详解Go语言运用广度优先搜索走迷宫
2021/06/23 Python