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 相关文章推荐
HTML上传控件取消选择
Mar 06 Javascript
from 表单提交返回值用post或者是get方法实现
Aug 21 Javascript
JavaScript节点及列表操作实例小结
Aug 05 Javascript
javascript数据结构之双链表插入排序实例详解
Nov 25 Javascript
javascript中利用柯里化函数实现bind方法【推荐】
Apr 29 Javascript
Jqprint实现页面打印
Jan 06 Javascript
关于Promise 异步编程的实例讲解
Sep 01 Javascript
angularjs数组判断是否含有某个元素的实例
Feb 27 Javascript
layui表格checkbox选择全选样式及功能的实例
Mar 07 Javascript
Node.js 使用request模块下载文件的实例
Sep 05 Javascript
Vue.js 中的 v-show 指令及用法详解
Nov 19 Javascript
vue视图不更新情况详解
May 16 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
人工智能开始玩《星际争霸2》 你的操作跟得上吗?
2017/08/11 星际争霸
apache+codeigniter 通过.htcaccess做动态二级域名解析
2012/07/01 PHP
php解析http获取的json字符串变量总是空白null
2015/03/02 PHP
PHP设置Cookie的HTTPONLY属性方法
2017/02/09 PHP
CSS心形加载的动画源码的实现
2021/03/09 HTML / CSS
Prototype源码浅析 Number部分
2012/01/16 Javascript
Node.js生成HttpStatusCode辅助类发布到npm
2013/04/09 Javascript
新增加的内容是如何将div的scrollbar自动移动最下面
2014/01/02 Javascript
javascript中indexOf技术详解
2015/05/07 Javascript
Nodejs爬虫进阶教程之异步并发控制
2016/02/15 NodeJs
jQuery+PHP+MySQL实现无限级联下拉框效果
2016/02/19 Javascript
js实现弹窗居中的简单实例
2016/10/09 Javascript
如何提高数据访问速度
2016/12/26 Javascript
javascript 显示全局变量与隐式全局变量的区别
2017/02/09 Javascript
JS按钮闪烁功能的实现代码
2017/07/21 Javascript
iview给radio按钮组件加点击事件的实例
2017/09/30 Javascript
JavaScript自执行函数和jQuery扩展方法详解
2017/10/27 jQuery
JS表单传值和URL编码转换
2018/03/03 Javascript
微信小程序canvas.drawImage完全显示图片问题的解决
2018/11/30 Javascript
vue 中 命名视图的用法实例详解
2019/08/14 Javascript
[44:30]完美世界DOTA2联赛PWL S2 GXR vs Magma 第一场 11.25
2020/11/26 DOTA
flask框架配置mysql数据库操作详解
2019/11/29 Python
Python3.7基于hashlib和Crypto实现加签验签功能(实例代码)
2019/12/04 Python
python 实现视频 图像帧提取
2019/12/10 Python
从pandas一个单元格的字符串中提取字符串方式
2019/12/17 Python
Python vtk读取并显示dicom文件示例
2020/01/13 Python
pyqt5 QlistView列表显示的实现示例
2020/03/24 Python
完美解决keras保存好的model不能成功加载问题
2020/06/11 Python
python3的pip路径在哪
2020/06/23 Python
详解如何使用Pytest进行自动化测试
2021/01/14 Python
美国中小型企业领先的办公家具供应商:Office Designs
2016/11/26 全球购物
POP文化和音乐灵感的时尚:Hot Topic
2019/06/19 全球购物
一些网络技术方面的面试题
2014/05/01 面试题
金融专业应届生求职信
2013/11/02 职场文书
护士毕业生自荐信
2014/02/07 职场文书
酒店端午节活动方案
2014/08/26 职场文书