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 相关文章推荐
js判断选择时间不能小于当前时间的示例代码
Sep 24 Javascript
如何将php数组或者对象传递给javascript
Mar 20 Javascript
jQuery.holdReady()使用方法
May 20 Javascript
jquery attr方法获取input的checked属性问题
May 26 Javascript
详解JavaScript对象序列化
Jan 19 Javascript
Bootstrap入门书籍之(零)Bootstrap简介
Feb 17 Javascript
jquery自适应布局的简单实例
May 28 Javascript
webpack配置文件和常用配置项介绍
Apr 28 Javascript
微信小程序开发中的疑问解答汇总
Jul 03 Javascript
详解在vue-cli中使用路由
Sep 25 Javascript
原生JS实现旋转轮播图+文字内容切换效果【附源码】
Sep 29 Javascript
JS实现星星海特效
Dec 24 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分页函数
2006/10/09 PHP
PHP中创建空文件的代码[file_put_contents vs touch]
2012/01/20 PHP
HTML DOM的nodeType值介绍
2011/03/31 Javascript
js动态生成Html元素实现Post操作(createElement)
2015/09/14 Javascript
JS组件Bootstrap按钮组与下拉按钮详解
2016/05/10 Javascript
JavaScript基础语法之js表达式
2016/06/07 Javascript
jquery+ajax实现省市区三级联动效果简单示例
2017/01/04 Javascript
BootStrap表单验证实例代码
2017/01/13 Javascript
jquery实现表单获取短信验证码代码
2017/03/13 Javascript
jQuery用noConflict代替$的实现方法
2017/04/12 jQuery
各种选择框jQuery的选中方法(实例讲解)
2017/06/27 jQuery
一个简单的node.js界面实现方法
2018/06/01 Javascript
nodejs 十六进制字符串型数据与btye型数据相互转换
2018/07/30 NodeJs
详解Vue项目在其他电脑npm run dev运行报错的解决方法
2018/10/29 Javascript
《javascript设计模式》学习笔记四:Javascript面向对象程序设计链式调用实例分析
2020/04/07 Javascript
python实现验证码识别功能
2018/06/07 Python
python使用wxpy实现微信消息防撤回脚本
2019/04/29 Python
python 中pyqt5 树节点点击实现多窗口切换问题
2019/07/04 Python
python实现截取屏幕保存文件,删除N天前截图的例子
2019/08/27 Python
一文解决django 2.2与mysql兼容性问题
2020/07/15 Python
HTML5标签与HTML4标签的区别示例介绍
2013/07/18 HTML / CSS
W Hamond官网:始于1979年的钻石专家
2020/07/20 全球购物
关于祖国的演讲稿
2014/05/04 职场文书
医药销售自荐书
2014/05/29 职场文书
汉语专业毕业生自荐信
2014/07/06 职场文书
2015教师见习期工作总结
2014/12/12 职场文书
领导欢迎词范文
2015/01/26 职场文书
导游欢送词
2015/01/31 职场文书
幼儿园大班个人总结
2015/02/28 职场文书
会计工作能力自我评价
2015/03/05 职场文书
2015年度班主任自我评价
2015/03/11 职场文书
毕业生爱心捐书倡议书
2015/04/27 职场文书
2016元旦主持人开场白
2015/12/03 职场文书
德劲DE1107指针试高灵敏度全波段收音机机评
2022/04/05 无线电
解决IIS7下无法绑定https主机的问题
2022/04/29 Servers
Android移动应用开发指南之六种布局详解
2022/09/23 Java/Android