隔离JavaScript的执行

Raw*_*den 13 javascript plugins module isolation

JS最让我感到困扰的一个限制是隔离代码执行能力差.

我希望能够控制执行代码的上下文,实现Script.createContextScript.runInContextnode.js中的内容类似的效果(节点使用绑定到V8引擎,因此我无法模拟它们的实现).

以下是我想隔离代码执行的一些原因:

  1. 将代码与全局命名空间(window对象及其中DOM)隔离开来,但是我需要能够在上下文中公开的对象上引用函数调用,这些对象必须同步执行,这使得使用WebWorker隔离几乎不可能.
  2. 通过隔离代码的执行,还可以在不再需要时释放其定义(内存管理).

我知道可以通过将脚本加载到a中来实现部分隔离执行,iframe但是这种方法非常繁重,并且为DOM的第二个实例使用了大量内存,这对于我正在尝试的操作是不需要的.

我需要共享构造函数定义以及在必须在主UI线程上运行的隔离容器/上下文之间共享的对象定义.主要是我想使用这些隔离的容器来托管插件/模块(迷你应用程序),每个插件/模块通过在自己的Context2D对象上调用绘图命令来呈现和动态更新视口.

如果这些容器没有在主UI线程上运行,那么代理调用就会非常困难,ctx.measureText()并且ctx.drawImage()由于无法在a中创建图像对象,所以这些都是无用的Worker.

有人知道未来的规范会使这成为可能吗?

是否有任何当前(隐藏的)浏览器端API可用于实现此目的?

是否可以更好地利用像Goggle的Dart VM这样的虚拟机并重新实现我当前的代码库? 我目前的代码库略高于20 000行代码.

在*中重新实施框架会更好吗?

jfr*_*d00 3

您可以使用简单的自执行函数对象将代码与全局命名空间隔离:

(function() {
   // all your code goes here
   // nobody outside of your code can reach your top level variables here
   // your top level variables are not on the window object

   // this is a protected, but top level variable
   var x = 3;

   // if you want anything to be global, you can assign it to the window object.
   window.myGlobal = {};

   function myTopLevelFunction(x,y,z) {
       // code here
   }

})();
Run Code Online (Sandbox Code Playgroud)

如果您希望拥有多个执行上下文并能够在它们之间共享,那么您将必须通过一个公开已知的位置进行会合,该位置可以是一个真正的全局变量,也可以是已知 DOM 对象上的属性或类似的东西。声明一个全局命名空间对象并使用该对象的属性来访问您在模块之间共享的内容是相对常见的。我知道它并不完全完美,但它确实有效。下面是使用单个全局命名空间对象的集合示例:

// module AAA
(function() {
   // module AAA code goes here

   // set up global namespace object and whatever references we want to be global
   window.myModuleTop = window.myModuleTop || {};
   myModuleTop.AAA = {};
   myModuleTop.AAA.myFuncA = function() {};

})();


// module BBB
(function() {
   // module BBB code goes here

   // set up global namespace object and whatever references we want to be global
   window.myModuleTop = window.myModuleTop || {};
   myModuleTop.BBB = {};
   myModuleTop.BBB.myFuncB = function() {};

})();
Run Code Online (Sandbox Code Playgroud)