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 相关文章推荐
js模拟实现Array的sort方法
Dec 11 Javascript
jquery 操作DOM案例代码分享
Apr 05 Javascript
FF火狐下获取一个元素同类型的相邻元素实现代码
Dec 15 Javascript
jQuery Masonry瀑布流插件使用详解
Nov 17 Javascript
javascript操作select元素实例分析
Mar 27 Javascript
纯javascript实现自动发送邮件
Oct 21 Javascript
JS与jQuery实现隔行变色的方法
Sep 09 Javascript
基于Vue如何封装分页组件
Dec 16 Javascript
js实现HTML中Select二级联动的实例
Jan 05 Javascript
vue 动态修改a标签的样式的方法
Jan 18 Javascript
JavaScript 截取字符串代码实例
Sep 05 Javascript
JS实现时间校验的代码
May 25 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
Windows 下安装 swoole 图文教程(php)
2017/06/05 PHP
详解PHP中的外观模式facade pattern
2018/02/05 PHP
Javascript客户端脚本的设计和应用
2006/08/21 Javascript
得到文本框选中的文字,动态插入文字的js代码
2007/03/07 Javascript
List Information About the Binary Files Used by an Application
2007/06/18 Javascript
js原生态函数中使用jQuery中的 $(this)无效的解决方法
2011/05/25 Javascript
javascipt基础内容--需要注意的细节
2013/04/10 Javascript
jquery实现相册一下滑动两次的方法
2015/02/09 Javascript
js实现表单Radio切换效果的方法
2015/08/17 Javascript
总结Node.js中的一些错误类型
2016/08/15 Javascript
JS读写CSS样式的方法汇总
2016/08/16 Javascript
jQuery实现的无限级下拉菜单功能示例
2016/09/12 Javascript
利用BootStrap弹出二级对话框的简单实现方法
2016/09/21 Javascript
Angularjs手动解析表达式($parse)
2016/10/12 Javascript
详解js的事件代理(委托)
2016/12/22 Javascript
Angular 4中如何显示内容的CSS样式示例代码
2017/11/06 Javascript
javascript中的replace函数(带注释demo)
2018/01/07 Javascript
js中getBoundingClientRect的作用及兼容方案详解
2018/02/01 Javascript
如何编写一个d.ts文件的步骤详解
2018/04/13 Javascript
动态加载JavaScript文件的3种方式
2018/05/05 Javascript
node thread.sleep实现示例
2018/06/20 Javascript
浅析Proxy可以优化vue的数据监听机制问题及实现思路
2018/11/29 Javascript
Vue 实现手动刷新组件的方法
2019/02/19 Javascript
Javascript 对象(object)合并操作实例分析
2019/07/30 Javascript
[00:35]DOTA2上海特级锦标赛 VP战队宣传片
2016/03/04 DOTA
gearman的安装启动及python API使用实例
2014/07/08 Python
使用 Python 实现微信公众号粉丝迁移流程
2018/01/03 Python
Opencv+Python 色彩通道拆分及合并的示例
2018/12/08 Python
python自定义函数实现最大值的输出方法
2019/07/09 Python
python实现单机五子棋
2020/08/28 Python
html5教程画矩形代码分享
2013/12/04 HTML / CSS
canvas如何实现多张图片编辑的图片编辑器
2020/03/10 HTML / CSS
周鸿祎:教你写创业计划书
2013/12/30 职场文书
国庆节演讲稿范文2014
2014/09/19 职场文书
校本培训个人总结
2015/02/28 职场文书
eclipse创建项目没有dynamic web的解决方法
2021/06/24 Java/Android