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 相关文章推荐
jquery ui dialog ie8出现滚动条的解决方法
Dec 06 Javascript
如何实现修改密码时密码框显示保存到cookie的密码
Dec 10 Javascript
node.js中watch机制详解
Nov 17 Javascript
javascript制作网页图片上实现下雨效果
Feb 26 Javascript
在JavaScript中正确引用bind方法的应用
May 11 Javascript
js拖拽的原型声明和用法总结
Apr 04 Javascript
设置jQueryUI DatePicker默认语言为中文
Jun 04 Javascript
javascript中Date对象的使用总结
Nov 21 Javascript
基于JavaScript定位当前的地理位置
Apr 11 Javascript
详解vue中使用express+fetch获取本地json文件
Oct 10 Javascript
Javascript中JSON数据分组优化实践及JS操作JSON总结
Dec 22 Javascript
jQuery实现的3D版图片轮播示例【滑动轮播】
Jan 18 jQuery
浅谈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设置编码格式的方法
2013/03/05 PHP
PHP基础之运算符的使用方法
2013/04/28 PHP
laravel 5 实现模板主题功能(续)
2015/03/02 PHP
php保存任意网络图片到服务器的方法
2015/04/14 PHP
谈谈PHP中substr和substring的正确用法及相关参数的介绍
2015/12/16 PHP
JavaScript设计模式之工厂方法模式介绍
2014/12/28 Javascript
jquery 插件实现多行文本框[textarea]自动高度
2015/03/04 Javascript
使用jquery清空、复位整个输入域
2015/04/02 Javascript
JavaScript队列、优先队列与循环队列
2016/11/14 Javascript
JavaScript trim 实现去除字符串首尾指定字符的简单方法
2016/12/27 Javascript
for循环 + setTimeout 结合一些示例(前端面试题)
2017/08/30 Javascript
如何制作一个Node命令行图像识别工具
2018/12/12 Javascript
JavaScript数据结构与算法之基本排序算法定义与效率比较【冒泡、选择、插入排序】
2019/02/21 Javascript
vue-router的钩子函数用法实例分析
2019/10/26 Javascript
leaflet加载geojson叠加显示功能代码
2020/02/21 Javascript
[10:18]2018DOTA2国际邀请赛寻真——Fnatic能否笑到最后?
2018/08/14 DOTA
python获取从命令行输入数字的方法
2015/04/29 Python
python处理Excel xlrd的简单使用
2017/09/12 Python
python机器学习之神经网络(三)
2017/12/20 Python
无法使用pip命令安装python第三方库的原因及解决方法
2018/06/12 Python
python+opencv实现阈值分割
2018/12/26 Python
python 搭建简单的http server,可直接post文件的实例
2019/01/03 Python
Python django框架应用中实现获取访问者ip地址示例
2019/05/17 Python
tensorflow 变长序列存储实例
2020/01/20 Python
马来西亚网上购物:Youbeli
2018/03/30 全球购物
美术专业自荐信
2014/07/07 职场文书
倡议书格式
2014/08/30 职场文书
自动化专业大学生职业生涯规划范文:爱拚才会赢
2014/09/12 职场文书
2014年学校国庆主题活动方案
2014/09/16 职场文书
生产车间主任岗位职责
2015/04/08 职场文书
2015年劳动部工作总结
2015/05/23 职场文书
杨善洲电影观后感
2015/06/04 职场文书
卡特教练观后感
2015/06/08 职场文书
2019年朋友圈经典励志语录50条
2019/07/05 职场文书
Node-Red实现MySQL数据库连接的方法
2021/08/07 MySQL