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 相关文章推荐
JObj预览一个JS的框架
Mar 13 Javascript
js jquery数组介绍
Jul 15 Javascript
ie下$.getJSON出现问题的解决方法
Feb 12 Javascript
javascript实现动态侧边栏代码
Feb 19 Javascript
node.js中的fs.lchmodSync方法使用说明
Dec 16 Javascript
DOM基础教程之事件类型
Jan 20 Javascript
JS中的THIS和WINDOW.EVENT.SRCELEMENT详解
May 25 Javascript
百度地图API之本地搜索与范围搜索
Jul 30 Javascript
Js的Array数组对象详解
Feb 22 Javascript
jQuery扩展实现text提示还能输入多少字节的方法
Nov 28 Javascript
Node.js的进程管理的深入理解
Jan 09 Javascript
React中的Context应用场景分析
Jun 11 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
ThinkPHP字符串函数及常用函数汇总
2014/07/18 PHP
php 时间time与日期date之间的使用详解及区别
2016/11/07 PHP
PHP大文件切割上传功能实例分析
2019/07/01 PHP
jQuery 操作下拉列表框实现代码
2010/02/22 Javascript
你必须知道的Javascript知识点之&quot;字面量和对应类型&quot;说明介绍
2013/04/23 Javascript
js自动下载文件到本地的实现代码
2013/04/28 Javascript
移动端H5开发 Turn.js实现很棒的翻书效果
2016/06/20 Javascript
解析JavaScript数组方法reduce
2016/12/12 Javascript
javascript函数的节流[throttle]与防抖[debounce]
2017/11/15 Javascript
jQuery中图片展示插件highslide.js的简单dom
2018/04/22 jQuery
微信小程序页面间传值与页面取值操作实例分析
2019/04/30 Javascript
环形加载进度条封装(Vue插件版和原生js版)
2019/12/04 Javascript
Vue 实现对quill-editor组件中的工具栏添加title
2020/08/03 Javascript
原生js生成图片验证码
2020/10/11 Javascript
vue项目打包后请求地址错误/打包后跨域操作
2020/11/04 Javascript
[40:10]2015国际邀请赛全明星表演赛
2015/08/07 DOTA
python使用xmlrpc实例讲解
2013/12/17 Python
python解析文件示例
2014/01/23 Python
python数字图像处理之高级滤波代码详解
2017/11/23 Python
python表格存取的方法
2018/03/07 Python
对python3标准库httpclient的使用详解
2018/12/18 Python
pycharm的console输入实现换行的方法
2019/01/16 Python
选择python进行数据分析的理由和优势
2019/06/25 Python
python 解决mysql where in 对列表(list,,array)问题
2020/06/06 Python
美国玛丽莎收藏奢华时尚商店:Marissa Collections
2016/11/21 全球购物
JD Sports意大利:英国篮球和运动时尚的领导者
2017/10/29 全球购物
linux面试题参考答案(8)
2016/04/19 面试题
总经理助理的职责
2014/03/14 职场文书
班级出游活动计划书
2014/08/15 职场文书
2014年财政局工作总结
2014/12/09 职场文书
小学语文新课改心得体会
2016/01/22 职场文书
100句人生哲理语录集锦:强者征服今天,懒汉坐等明天
2019/10/18 职场文书
Java面试题冲刺第十七天--基础篇3
2021/08/07 面试题
详解解Django 多对多表关系的三种创建方式
2021/08/23 Python
Nginx实现负载均衡的项目实践
2022/03/18 Servers
Python实现聚类K-means算法详解
2022/07/15 Python