JS-Interpreter 中文文檔(翻譯)

JS-Interpreter 是主要配合 Google 的可視化編程工具 Blockly 的一個庫
這里翻譯了它的文檔
原翻譯在 GitHub 上 原翻譯

JS-Interpreter 中文文檔

翻譯自 JS-Interpreter Documentation

JS-Interpreter 是用 JavaScript 寫的具有沙箱環(huán)境的 JavaScript 解析器. 它可以讓你任意的, 一行一行地執(zhí)行 JavaScript 代碼. 它的執(zhí)行過程與主要的 JavaScript 代碼環(huán)境是分離開的. JS-Interpreter 的多個實例可以允許多線程并發(fā)JavaScript, 而無需使用Web Workers.

在這可以你可以嘗試一下它 : JS-Interpreter demo

獲取它的源代碼 源代碼

使用方法

  • 引入這兩個 JavaScript 源代碼
<script src="acorn.js"></script>
<script src="interpreter.js"></script>
  • 當(dāng)然, 你也可以選擇它們的壓縮包(70kb)
<script src="acorn_interpreter.js"></script>

然后, 實例化一個 interpreter, 并且把你需要還原的 JavaScript 代碼放進(jìn)去

var myCode = 'var a=1; for(var i=0;i<4;i++){a*=i;} a;';
var myInterpreter = new Interpreter(myCode);

可以隨時添加其他 JavaScript 代碼(經(jīng)常用于交互式調(diào)用(譯者注:我猜是事件之類的)預(yù)先定義的函數(shù))

myInterpreter.appendCode('foo();');

為了去一步一步地跑這些代碼, 需要重復(fù)地去調(diào)用 step 函數(shù), 直到它返回 false

function nextStep() {
  if (myInterpreter.step()) {
    window.setTimeout(nextStep, 0);
  }
}
nextStep();

或者, 如果已知代碼里面沒有死循環(huán), 則可以直接調(diào)用 run 函數(shù)執(zhí)行一次完成全部的 step

myInterpreter.run();

在代碼遇到異步API調(diào)用的情況下(見下文), 如果阻塞了并且需要在以后重新執(zhí)行, run將返回 true

外部的 API

eval 類似, 最后一個語句的結(jié)果可以在 myInterpreter.value 中找到

var myInterpreter = new Interpreter('6 * 7');
myInterpreter.run();
alert(myInterpreter.value);

另外, API 的調(diào)用可以在創(chuàng)建的時候被添加到 interpreter, 下面是添加了 alert() 和 變量 url

var initFunc = function(interpreter, scope) {
  interpreter.setProperty(scope, 'url', String(location));

  var wrapper = function(text) {
    return alert(text);
  };
  interpreter.setProperty(scope, 'alert',
      interpreter.createNativeFunction(wrapper));
};
var myInterpreter = new Interpreter(myCode, initFunc);

JSON demo 是在瀏覽器和 interpreter 之間轉(zhuǎn)換 JSON 的一個例子. 有關(guān)更復(fù)雜的示例, 請參閱 initGlobalScope 函數(shù), 該函數(shù)為 Math, Array, Function 和其他全局變量創(chuàng)建API.

異步的 API 函數(shù)也可以被包起來, 使它們看起來與解釋器同步. 例如, 可以在 initFunc 中定義返回 XMLHttpRequest 內(nèi)容的getXhr(url)函數(shù), 如下所示:

var wrapper = function(href, callback) {
  var req = new XMLHttpRequest();
  req.open('GET', href, true);
  req.onreadystatechange = function() {
    if (req.readyState == 4 && req.status == 200) {
      callback(req.responseText);
    }
  };
  req.send(null);
};
interpreter.setProperty(scope, 'getXhr',
    interpreter.createAsyncFunction(wrapper));

上面的代碼片段使用了 createAsyncFunction, 正如之前使用的 createNativeFunction 一樣. 區(qū)別是被包裹(wrapped)的異步函數(shù)的返回值被忽略了. 取而代之的是, 當(dāng) wrapper 函數(shù)被調(diào)用的時候, 會有一個回調(diào)函數(shù)會被傳遞進(jìn)去. 當(dāng) wrapper 函數(shù)要有返回值的時候, 它會調(diào)用這個回調(diào)函數(shù), 這樣你就有了它的返回值了. 從 JS-Interpreter 內(nèi)部運行的代碼的角度來看, 進(jìn)行了函數(shù)調(diào)用并立即返回結(jié)果.

這里是一個能跑的例子 async demo

序列化

JS-Interpreter的一個獨特功能是它能夠暫停執(zhí)行, 序列化(把變量從內(nèi)存中變成可存儲或傳輸?shù)倪^程)當(dāng)前狀態(tài), 然后在稍后的時間點恢復(fù)執(zhí)行. 保留了循環(huán), 變量, 閉包和所有其他狀態(tài).

使用這個功能包括連續(xù)執(zhí)行在服務(wù)器重新啟動后繼續(xù)執(zhí)行的程序, 加載已計算到某個點的堆棧映像, 分支執(zhí)行或回滾到一個已經(jīng)被存儲了的狀態(tài).

一個缺點是序列化格式不是可讀的, 并且也不能保證 JS-Interpreter 的未來版本能夠解析舊版本的序列化. 另一個缺點是序列化格式相當(dāng)大; 在標(biāo)準(zhǔn)的 polyfill 下, 它的開銷為 60kb.

這里是一個能跑的例子 serialization demo

多線程

JavaScript 是單線程的語言, 但是 JS-Interpreter 允許同時運行多個進(jìn)程. 創(chuàng)建兩個或更多的獨立進(jìn)程, 它們彼此分開運行是很簡單的: 只需創(chuàng)建兩個或多個 Interpreter 實例, 每個實例都有自己的代碼, 并且可以調(diào)用每個 interpreter 的 step 函數(shù). 它們可以通過提供的任何外部 API 間接地相互通信.

稍微復(fù)雜的情況是兩個或多個線程想要共享相同全局作用域. 要實現(xiàn)這一點, 1)創(chuàng)建一個JS-Interpreter, 2)創(chuàng)建一個單獨的堆棧列表, 3)將每個堆棧的根節(jié)點的.scope屬性分配給 interpreter 的 .global屬性, 4)然后將所需的堆棧分配給調(diào)用 step 之前interpreter的 stateStack 屬性.

這里有一個例子: tread demo

限制

interpreter 實現(xiàn)的 JavaScript 版本與在瀏覽器中執(zhí)行的版本略有不同

  • API
    沒有暴露 DOM 的 API, 這也是沙箱的重點. 如果您需要這些, 請編寫自己的接口

  • ES6
    最近添加的 JavaScript (例如 let 或 Set)未實現(xiàn). 如果您需要超過 ES5, 請為這個項目貢獻(xiàn)代碼.

  • toString & valueOf
    將對象轉(zhuǎn)換為 JS-Interpreter 的原語(primitives)時,不會調(diào)用用戶創(chuàng)建的函數(shù)

  • 性能
    interpreter 并不是十分快, 它大概比原生 JS 慢 200 倍

依賴

唯一的依賴就是 Acorn, 這是 Marijn Haverbeke 寫的 JavaScript 的還原器. 它已經(jīng)被包含進(jìn)了 JS-Interpreter

兼容性

需要瀏覽器支持使用 Object.create(null)在 Acorn 和 JS-Interpreter 中創(chuàng)建 Object. 這最低的瀏覽器要求:

  • Chrome 5
  • Firefox 4.0
  • IE 9
  • Opera 11.6
  • Safari 5

免責(zé)聲明

這個并不是 Google 官方的產(chǎn)品

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,347評論 25 708
  • 月上柳梢頭, 人約黃昏後。
    喜亭_bf8f閱讀 201評論 1 11
  • 可以說,這一次往東北去,是不曾有任何計劃的。計劃之外,倘若有心,總有驚喜,概不例外。 去到的時候,已經(jīng)是晚上了,氣...
    Philip_Lang閱讀 693評論 3 5
  • 草木漸深。不可說的部分越拉越長 似盲僧,看著昏暗廟宇中 燭火上跳躍的蓮花一朵一朵湮滅 沉落 陷入冰冷凝固的蠟池 他...
    沐朝閱讀 424評論 1 1

友情鏈接更多精彩內(nèi)容