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 相关文章推荐
javascript学习(一)构建自己的JS库
Jan 02 Javascript
ScrollDown的基本操作示例
Jun 09 Javascript
获取3个数组不重复的值的具体实现
Dec 30 Javascript
使用CSS样式position:fixed水平滚动的方法
Feb 19 Javascript
基于jQuery实现文本框缩放以及上下移动功能
Nov 24 Javascript
JavaScript中的包装对象介绍
Jan 27 Javascript
javascript格式化指定日期对象的方法
Apr 21 Javascript
关于JS变量和作用域详解
Jul 28 Javascript
微信小程序 http请求详细介绍
Oct 09 Javascript
理解JavaScript原型链
Oct 25 Javascript
解决layer弹出层中表单不起作用的问题
Sep 09 Javascript
Vue+element+cookie记住密码功能的简单实现方法
Sep 20 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
服务器web工具 php环境下
2010/12/29 PHP
php中json_encode中文编码问题分析
2011/09/13 PHP
PHP常用正则表达式集锦
2014/08/17 PHP
PHP简单的MVC框架实现方法
2015/12/01 PHP
thinkPHP框架对接支付宝即时到账接口回调操作示例
2016/11/14 PHP
TP3.2.3框架文件上传操作实例详解
2020/01/23 PHP
PHP设计模式(四)原型模式Prototype实例详解【创建型】
2020/05/02 PHP
Javascript实例教程(19) 使用HoTMetal(2)
2006/12/23 Javascript
jQuery 前的按键判断代码
2010/03/19 Javascript
30个最好的jQuery 灯箱插件分享
2011/04/25 Javascript
模拟多级复选框效果的jquery代码
2013/08/13 Javascript
JS、jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例分享
2014/04/11 Javascript
解决wx.onMenuShareTimeline出现的问题
2016/08/16 Javascript
前端面试题及答案整理(二)
2016/08/26 Javascript
jQuery实现简单弹窗遮罩效果
2017/02/27 Javascript
vue实现移动端图片裁剪上传功能
2020/08/18 Javascript
基于bootstrap写的一点localStorage本地储存
2017/11/21 Javascript
vue2.0父子组件间传递数据的方法
2018/08/16 Javascript
vue filter 完美时间日期格式的代码
2019/08/14 Javascript
vue实现虚拟列表功能的代码
2020/07/28 Javascript
vue通过接口直接下载java生成好的Excel表格案例
2020/10/26 Javascript
用js实现放大镜效果
2020/10/28 Javascript
[03:56]显微镜下的DOTA2第十一期——鬼畜的死亡先知播音员
2014/06/23 DOTA
[47:20]DAC2018 4.4 淘汰赛 Optic vs Mineski 第一场
2018/04/05 DOTA
[32:47]完美世界DOTA2联赛 GXR vs IO 第二场 11.07
2020/11/09 DOTA
MAC中PyCharm设置python3解释器
2017/12/15 Python
使用Python测试Ping主机IP和某端口是否开放的实例
2019/12/17 Python
Python大批量搜索引擎图像爬虫工具详解
2020/11/16 Python
Hanky Panky官方网站:内衣和睡衣
2019/07/25 全球购物
班主任工作年限证明
2014/01/12 职场文书
学校消防安全制度
2014/01/30 职场文书
简单的大学生自我鉴定
2014/02/18 职场文书
《圆的面积》教学反思
2016/02/19 职场文书
《吃水不忘挖井人》教学反思
2016/02/22 职场文书
施工安全责任协议书
2016/03/23 职场文书
Nginx本地配置SSL访问的实例教程
2022/05/30 Servers