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 preload&amp;lazy load
May 13 Javascript
extjs grid设置某列背景颜色和字体颜色的实现方法
Sep 06 Javascript
JavaScript中的isXX系列是否继续使用的分析
Apr 16 Javascript
jquery.tmpl JQuery模板插件
Oct 10 Javascript
jquery validate添加自定义验证规则(验证邮箱 邮政编码)
Dec 04 Javascript
jQuery实现自动与手动切换的滚动新闻特效代码分享
Aug 27 Javascript
一些实用性较高的js方法
Apr 19 Javascript
基于Phantomjs生成PDF的实现方法
Nov 07 Javascript
Ionic2开发环境搭建教程
Aug 20 Javascript
vue 数组和对象不能直接赋值情况和解决方法(推荐)
Oct 25 Javascript
Vue使用NProgress的操作过程解析
Oct 10 Javascript
Vue使用vue-recoure + http-proxy-middleware + vuex配合promise实现基本的跨域请求封装
Oct 21 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 远程图片保存到本地的函数类
2008/12/08 PHP
php获取网页标题和内容函数(不包含html标签)
2014/02/03 PHP
Javascript调用XML制作连动下拉列表框
2006/06/25 Javascript
javascript Discuz代码中的msn聊天小功能
2008/05/25 Javascript
Js四则运算函数代码
2012/07/21 Javascript
常见JS验证脚本汇总
2015/12/01 Javascript
JS定义类的六种方式详解
2016/05/12 Javascript
总结jQuery插件开发中的一些要点
2016/05/16 Javascript
JS控制弹出悬浮窗口(一览画面)的实例代码
2016/05/30 Javascript
javascript中递归的两种写法
2017/01/17 Javascript
js Canvas绘制圆形时钟教程
2017/02/06 Javascript
jQuery使用JSONP实现跨域获取数据的三种方法详解
2017/05/04 jQuery
详解从Vue.js源码看异步更新DOM策略及nextTick
2017/10/11 Javascript
推荐几个不错的console调试技巧实现
2019/12/20 Javascript
理解Proxy及使用Proxy实现vue数据双向绑定操作
2020/07/18 Javascript
解决vue自定义指令导致的内存泄漏问题
2020/08/04 Javascript
使用Python的Tornado框架实现一个简单的WebQQ机器人
2015/04/24 Python
Python 的描述符 descriptor详解
2016/02/27 Python
使用Python完成15位18位身份证的互转功能
2019/11/06 Python
Python函数的返回值、匿名函数lambda、filter函数、map函数、reduce函数用法实例分析
2019/12/26 Python
python列表返回重复数据的下标
2020/02/10 Python
python使用Geany编辑器配置方法
2020/02/21 Python
使用Dajngo 通过代码添加xadmin用户和权限(组)
2020/07/03 Python
详解python 支持向量机(SVM)算法
2020/09/18 Python
美国男士西装打折店:Jos. A. Bank
2017/11/13 全球购物
学生爱国演讲稿
2014/01/14 职场文书
会计学专业学生的求职信范文
2014/01/27 职场文书
捐款倡议书范文
2014/02/02 职场文书
高二物理教学反思
2014/02/08 职场文书
社区工作者感言
2014/03/02 职场文书
毕业晚会主持词
2014/03/24 职场文书
2014年党员创先争优承诺书
2014/05/29 职场文书
工程售后服务方案
2014/06/08 职场文书
党员群众路线教育实践活动剖析材料
2014/10/10 职场文书
事业单位考察材料范文
2014/12/25 职场文书
小学开学典礼新闻稿
2015/07/17 职场文书