VM モジュールは NodeJS のコア モジュールであり、require メソッドと NodeJS の操作メカニズムをサポートします。場合によっては、特別なことを行うために VM テンプレートを使用することもあります。この記事では、Node の VM モジュールについて詳しく説明します。お役に立てば幸いです。
#リファレンス vm 仮想マシン | Node 公式 Web サイトhttp://nodejs.cn/api/vm.html前の記事で、問題について触れました。
文字列を実行用の JS に変換するにはどうすればよいでしょうか?
eval function と new Function という 2 つのメソッドを詳しく紹介しました。
ここで、Function コンストラクターによって作成された関数は、現在の環境のクロージャを作成するのではなく、常にグローバル環境で作成されるため、実行時に作成されることを再度強調する必要があります。アクセスできるのはグローバル変数と独自のローカル変数のみであり、
Function コンストラクターによって作成されたスコープ内の変数にはアクセスできません。これは、
eval を使用して関数を作成するコードを実行することとは異なります。
global.a = 100; // 挂在到全局对象global上 var b = 200; // this !== global new Function("console.log(a)")() // 100 new Function("console.log(b)")() // b is not defined
Function はグローバル変数を取得できるため、変数汚染が依然として存在する可能性があります。
関数は
モジュールエンジンの実装原理であり、今後別途記事で解説する予定です。
vmmodule
という別の解決策があります。
変数の汚染という概念を強調してきました。
VM の特徴は環境に影響されないことであり、サンドボックス環境 (サンドボックスモードはモジュールが動作する環境を提供します)他のモジュールとそのプライベート サンドボックスに影響を与えることなく)。
const vm = require('vm') global.a = 100; // 运行在当前环境中[当前作用域] vm.runInThisContext('console.log(a)'); // 100 // 运行在新的环境中[其他作用域] vm.runInNewContext('console.log(a)'); // a is not defined
Node.js の グローバル変数は複数のモジュールで共有されるため、グローバルでプロパティを定義しないようにしてください。 デモ内の定義は、理解を容易にするためのものです。
同じディレクトリにglobal.a = 100; を定義するファイル 1.js があるとします。ここで、このファイルを紹介します
requrie(./1); console.log(a); // 100
Node のグローバル変数は複数のモジュールで共有されます。
その理由は、Node 環境にはグローバルな実行コンテキストが存在するためです。
// 模拟一下Node的全局环境 // vm.runInThisContext在当前全局环境执行,但不会产生新函数 - function(exports, module, require, __dirname, __filename){ // ... } - vm.runInThisContext ... // vm.runInNewContext在全局环境之外执行 vm.runInNewContext ...
vm.runInThisContext は
global のグローバル変数にアクセスできますが、カスタム変数にはアクセスできません。ただし、
vm.runInNewContext は
global にアクセスできず、カスタム変数にもアクセスできず、まったく新しい実行コンテキストに存在します。
require は
vm.runInThisContext を通じて実現されます。
requireは以下の4つのステップに分けられます。
を通じて JS 構文に変換します。
と b.js// 文件a通过module.exports导出一个变量,在文件b中使用require进行接收。
// a.js
module.exports = "a"
// b.js
let a = require('./a');
console.log(a); // a
インポートする必要のあるファイルの内容を受信する必要のあるファイルに挿入すると、次のようになります。
let a = module.exports = "a";
let a = (function(exports, module, require, __dirname, __filename){ module.exports = "a"; return module.exports })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
封装成函数的原因,我们可以参考下面这个例子。
假设我们现在传入的不是字符串,而是一个函数。
// a.js var a = 100; module.exports = function(){}
这样我们在解析的时候,就会被解析成下面这种格式
let a = (function(exports, module, require, __dirname, __filename){ var a = 100; module.exports = function(){}; return module.exports })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
我们导出的是 module.exports
,所以在模块文件中定义的变量a,也只属于当前这个执行上下文。
在解析的时候,变量a 会被放到函数中。真正的实现了 作用域分离。
vm.runInThisContext
解析成可执行的Js代码
我们处理过的代码会以字符串的形式存在,所以我们需要通过vm.runInThisContext
将字符串进行解析。
进行代码调用
在此之前,我们其实还需要对代码进行调试。
更多node相关知识,请访问:nodejs 教程!!
以上がNode.js の VM モジュールの詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。