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使用办法
Apr 01 Javascript
js中eval详解
Mar 30 Javascript
JS中Iframe之间传值及子页面与父页面应用
Mar 11 Javascript
jQuery之DOM对象和jQuery对象的转换与区别分析
Jan 08 Javascript
javascript循环链表之约瑟夫环的实现方法
Jan 16 Javascript
微信小程序 图片加载(本地,网路)实例详解
Mar 10 Javascript
详解vuex 中的 state 在组件中如何监听
May 23 Javascript
代码详解JS操作剪贴板
Feb 11 Javascript
微信小程序动画(Animation)的实现及执行步骤
Oct 28 Javascript
基于vue如何发布一个npm包的方法步骤
May 15 Javascript
vue点击页面空白处实现保存功能
Nov 06 Javascript
Vue+Element-U实现分页显示效果
Nov 15 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 中的类
2006/10/09 PHP
php获取域名的google收录示例
2014/03/24 PHP
destoon文章模块调用企业会员资料的方法
2014/08/22 PHP
php计划任务之ignore_user_abort函数实现方法
2015/01/08 PHP
微信支付开发维权通知实例
2016/07/12 PHP
php使用curl详细解析及问题汇总
2016/08/11 PHP
php 二维数组时间排序实现代码
2016/11/19 PHP
PHP基于PDO实现的SQLite操作类【包含增删改查及事务等操作】
2017/06/21 PHP
javascript返回顶部效果(自写代码)
2013/01/06 Javascript
js获得指定控件输入光标的坐标兼容IE,Chrome,火狐等多种主流浏览器
2013/05/21 Javascript
不要使用jQuery触发原生事件的方法
2014/03/03 Javascript
JS基于Mootools实现的个性菜单效果代码
2015/10/21 Javascript
轻松掌握JavaScript享元模式
2016/08/27 Javascript
快速移动鼠标触发问题及解决方法(ECharts外部调用保存为图片操作及工作流接线mouseenter和mouseleave)
2016/08/29 Javascript
手机浏览器 后退按钮强制刷新页面方法总结
2016/10/09 Javascript
微信开发之调起摄像头、本地展示图片、上传下载图片实例
2016/12/08 Javascript
JavaScript Canvas绘制圆形时钟效果
2020/08/20 Javascript
vue.js实现的幻灯片功能示例
2019/01/18 Javascript
layui使用表格渲染获取行数据的例子
2019/09/13 Javascript
Element-Ui组件 NavMenu 导航菜单的具体使用
2019/10/24 Javascript
Vue 通过公共字段,拼接两个对象数组的实例
2019/11/07 Javascript
Vue实现购物车实例代码两则
2020/05/30 Javascript
JS判断数组是否包含某元素实现方法汇总
2020/06/24 Javascript
JS遍历树层级关系实现原理解析
2020/08/31 Javascript
python实现上传下载文件功能
2020/11/19 Python
Python设计模式之备忘录模式原理与用法详解
2019/01/15 Python
Atom Python 配置Python3 解释器的方法
2019/08/28 Python
keras load model时出现Missing Layer错误的解决方式
2020/06/11 Python
在pytorch中动态调整优化器的学习率方式
2020/06/24 Python
程序员岗位职责
2013/11/11 职场文书
房屋租赁协议书
2014/04/10 职场文书
爱与责任师德演讲稿
2014/08/26 职场文书
追悼词范文大全
2015/06/23 职场文书
建议书的格式及范文
2015/09/14 职场文书
四年级数学教学反思
2016/02/16 职场文书
php中pcntl_fork详解
2021/04/01 PHP