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 相关文章推荐
ajax页面无刷新 IE下遭遇Ajax缓存导致数据不更新的问题
Dec 11 Javascript
获取非最后一列td值并将title设为该值的方法
Oct 30 Javascript
JavaScript中的this关键字使用详解
Aug 14 Javascript
浅谈JavaScript 浏览器对象
Jun 03 Javascript
AngularJS 路由和模板实例及路由地址简化方法(必看)
Jun 24 Javascript
深入学习jQuery中的data()
Dec 22 Javascript
js实现简单的手风琴效果
Feb 27 Javascript
原生JS实现循环Nodelist Dom列表的4种方式示例
Feb 11 Javascript
Cordova(ionic)项目实现双击返回键退出应用
Sep 17 Javascript
对Layer弹窗使用及返回数据接收的实例详解
Sep 26 Javascript
javascript 高级语法之继承的基本使用方法示例
Nov 11 Javascript
vue使用screenfull插件实现全屏功能
Sep 17 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通用检测函数集合
2011/02/08 PHP
php简单的留言板与回复功能具体实现
2014/02/19 PHP
基于PHP后台的Android新闻浏览客户端
2016/05/23 PHP
PHP实现的下载远程文件类定义与用法示例
2017/07/05 PHP
Laravel 实现密码重置功能
2018/02/23 PHP
laravel框架模型和数据库基础操作实例详解
2020/01/25 PHP
关于Ext中form移除textfield方法:hide(),setVisible(false),remove()
2010/12/02 Javascript
formValidator3.3的ajaxValidator一些异常分析
2011/07/12 Javascript
jquery实现的导航固定效果
2014/04/28 Javascript
如何解决谷歌浏览器下jquery无法获取图片的尺寸
2015/09/10 Javascript
浅析创建javascript对象的方法
2016/05/13 Javascript
原生js获取浏览器窗口及元素宽高常用方法集合
2017/01/18 Javascript
JS 中使用Promise 实现红绿灯实例代码(demo)
2017/10/20 Javascript
Vue.extend实现挂载到实例上的方法
2019/05/01 Javascript
Vue中跨域及打包部署到nginx跨域设置方法
2019/08/26 Javascript
javascript设计模式 ? 代理模式原理与用法实例分析
2020/04/16 Javascript
Vue中key的作用示例代码详解
2020/06/10 Javascript
[02:40]DOTA2英雄基础教程 先知
2013/11/29 DOTA
python获取Linux下文件版本信息、公司名和产品名的方法
2014/10/05 Python
在Python的Django框架中包装视图函数
2015/07/20 Python
TensorFlow数据输入的方法示例
2018/06/19 Python
pandas重新生成索引的方法
2018/11/06 Python
Python基于机器学习方法实现的电影推荐系统实例详解
2019/06/25 Python
Apache,wsgi,django 程序部署配置方法详解
2019/07/01 Python
关于Numpy数据类型对象(dtype)使用详解
2019/11/27 Python
tensorflow指定GPU与动态分配GPU memory设置
2020/02/03 Python
意大利辅助药品、药物和补品在线销售:FarmaEurope
2020/04/29 全球购物
邀请函格式范文
2015/02/02 职场文书
2015年化工厂工作总结
2015/05/04 职场文书
预备党员转正意见
2015/06/01 职场文书
特种设备安全管理制度
2015/08/06 职场文书
小学数学教师研修日志
2015/11/13 职场文书
人民调解协议书
2016/03/21 职场文书
话题作文之成长
2019/12/09 职场文书
Redis 操作多个数据库的配置的方法实现
2022/03/23 Redis
CSS中float高度塌陷问题的四种解决方案
2022/04/18 HTML / CSS