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 相关文章推荐
运用Windows XP附带的Msicuu.exe、Msizap.exe来彻底卸载顽固程序
Apr 21 Javascript
终于解决了IE8不支持数组的indexOf方法
Apr 03 Javascript
有关于eclipse配置spket需要注意的一些地方
Apr 07 Javascript
js中window.open打开一个新的页面
Aug 10 Javascript
JS正则验证多个邮箱完整实例【邮箱用分号隔开】
Apr 19 Javascript
javascript基础进阶_深入剖析执行环境及作用域链
Sep 05 Javascript
Vue下路由History模式打包后页面空白的解决方法
Jun 29 Javascript
layui radio性别单选框赋值方法
Aug 15 Javascript
初探Vue3.0 中的一大亮点Proxy的使用
Dec 06 Javascript
微信公众号H5之微信分享常见错误和问题(小结)
Nov 14 Javascript
JavaScript实现PC端四格密码输入框功能
Feb 19 Javascript
理解JavaScript中的对象
Aug 25 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获取数组中某元素的位置及array_keys函数应用
2013/01/29 PHP
PHP实现对文本数据库的常用操作方法实例演示
2014/07/04 PHP
curl和libcurl的区别简介
2015/07/01 PHP
JQuery 网站换肤功能实现代码
2009/11/02 Javascript
关于jquery ajax 调用带参数的webservice返回XML数据一个小细节
2012/07/31 Javascript
批量实现面向对象的实例代码
2013/07/01 Javascript
分享33个jQuery与CSS3实现的绚丽鼠标悬停效果
2014/12/15 Javascript
javascript 闭包详解
2015/02/15 Javascript
微信小程序 支付功能(前端)的实现
2017/05/24 Javascript
简单快速的实现js计算器功能
2017/08/17 Javascript
es6数组的flat(),flatMap()函数用法实例分析
2020/04/18 Javascript
详解Vue+elementUI build打包部署后字体图标丢失问题
2020/07/13 Javascript
原生JS实现音乐播放器
2021/01/26 Javascript
python定时复制远程文件夹中所有文件
2019/04/30 Python
python中的单引号双引号区别知识点总结
2019/06/23 Python
Python定时任务工具之APScheduler使用方式
2019/07/24 Python
python文字和unicode/ascll相互转换函数及简单加密解密实现代码
2019/08/12 Python
用Python将Excel数据导入到SQL Server的例子
2019/08/24 Python
Django Form and ModelForm的区别与使用
2019/12/06 Python
如何定义TensorFlow输入节点
2020/01/23 Python
Python脚本实现Zabbix多行日志监控过程解析
2020/08/26 Python
JD Sports马来西亚:英国领先的运动鞋和运动服饰零售商
2018/03/13 全球购物
PHP经典面试题
2016/09/03 面试题
Java如何支持I18N?
2016/10/31 面试题
住房公积金接收函
2014/01/09 职场文书
五十岁生日宴会答谢词
2014/01/15 职场文书
汽车专业学生自我评价
2014/01/19 职场文书
《中华少年》教学反思
2014/02/15 职场文书
保密工作责任书
2014/04/16 职场文书
《长征》教学反思
2014/04/27 职场文书
个人简历自我评价怎么写
2015/03/10 职场文书
2015年前台文员工作总结
2015/05/18 职场文书
办公室主任岗位竞聘书
2015/09/15 职场文书
婚礼答谢词范文
2015/09/29 职场文书
HTML常用标签超详细整理
2022/03/19 HTML / CSS
深入理解 Golang 的字符串
2022/05/04 Golang