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 相关文章推荐
Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
Feb 13 Javascript
js控制input输入字符解析
Dec 27 Javascript
jquery each的几种常用的使用方法示例
Jan 21 Javascript
14款经典网页图片和文字特效的jQuery插件-前端开发必备
Aug 25 Javascript
JS日期格式化之javascript Date format
Oct 01 Javascript
webix+springmvc session超时跳转登录页面
Oct 30 Javascript
Javascript Function.prototype.bind详细分析
Dec 29 Javascript
微信小程序 摇一摇抽奖简单实例实现代码
Jan 09 Javascript
删除table表格行的实例讲解
Sep 21 Javascript
vue、react等单页面项目应该这样子部署到服务器
Jan 03 Javascript
手把手带你搭建一个node cli的方法示例
Aug 07 Javascript
js实现飞机大战小游戏
Aug 26 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
CI(CodeIgniter)框架配置
2014/06/10 PHP
PHP独立Session数据库存储操作类分享
2014/06/11 PHP
深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP
2012/01/15 Javascript
利用毫秒减值计算时长的js代码
2013/09/22 Javascript
以JSON形式将JS中Array对象数组传至后台的方法
2014/01/06 Javascript
把文本中的URL地址转换为可点击链接的JavaScript、PHP自定义函数
2014/07/29 Javascript
JavaScript编程学习技巧汇总
2016/02/21 Javascript
iScroll.js 使用方法参考
2016/05/16 Javascript
非常酷炫的Bootstrap图片轮播动画
2016/05/27 Javascript
jQuery解决IE6、7、8不能使用 JSON.stringify 函数的问题
2016/05/31 Javascript
底部悬浮通栏可以关闭广告位的实现方法
2016/06/01 Javascript
js中获取时间new Date()的全面介绍
2016/06/20 Javascript
jq给页面添加覆盖层遮罩的实例
2017/02/16 Javascript
移动端Ionic App 资讯上下循环滚动的实现代码(跑马灯效果)
2017/08/29 Javascript
详解JS构造函数中this和return
2017/09/16 Javascript
vue 音乐App QQ音乐搜索列表最新接口跨域设置方法
2018/09/25 Javascript
详解VSCode配置启动Vue项目
2019/05/14 Javascript
Vuex,iView UI面包屑导航使用扩展详解
2019/11/04 Javascript
python中类的一些方法分析
2014/09/25 Python
详解详解Python中writelines()方法的使用
2015/05/25 Python
Python简单遍历字典及删除元素的方法
2016/09/18 Python
python re模块的高级用法详解
2018/06/06 Python
Python基于Logistic回归建模计算某银行在降低贷款拖欠率的数据示例
2019/01/23 Python
Python使用字典实现的简单记事本功能示例
2019/08/15 Python
python输出pdf文档的实例
2020/02/13 Python
python异常处理之try finally不报错的原因
2020/05/18 Python
python 3.8.3 安装配置图文教程
2020/05/21 Python
python读取excel数据绘制简单曲线图的完整步骤记录
2020/10/30 Python
信息专业本科生个人的自我评价
2013/10/28 职场文书
高一政治教学反思
2014/01/28 职场文书
妇联主席先进事迹
2014/05/18 职场文书
党员四风剖析材料
2014/08/27 职场文书
小学国旗下的演讲稿
2014/08/28 职场文书
九寨沟导游词
2015/02/02 职场文书
2016学习依法治国心得体会
2016/01/15 职场文书
详解Golang如何优雅的终止一个服务
2022/03/21 Golang