以前,经常使用作为沙箱。
上面代码中,<iframe>
的全局对象是独立的(iframe.contentWindow
)。Realm API 可以取代这个功能。
const globalOne = window;
const globalTwo = new Realm().global;
上面代码中,Realm API
单独提供了一个全局对象new Realm().global
。
Realm API 提供一个Realm()
构造函数,用来生成一个 Realm 对象。该对象的global
属性指向一个新的顶层对象,这个顶层对象跟原始的顶层对象类似。
下面的代码可以证明,Realm 顶层对象与原始顶层对象是两个对象。
let a1 = globalOne.evaluate('[1,2,3]');
let a2 = globalTwo.evaluate('[1,2,3]');
a2 instanceof globalOne.Array; // false
上面代码中,Realm 沙箱里面的数组的原型对象,跟原始环境里面的数组是不一样的。
Realm 沙箱里面只能运行 ECMAScript 语法提供的 API,不能运行宿主环境提供的 API。
上面代码中,Realm 沙箱里面没有console
对象,导致报错。因为console
不是语法标准,是宿主环境提供的。
globalTwo.console = globalOne.console;
Realm()
构造函数可以接受一个参数对象,该参数对象的intrinsics
属性可以指定 Realm 沙箱继承原始顶层对象的方法。
上面代码中,正常情况下,沙箱的JSON
方法不同于原始的JSON
对象。但是,Realm()
构造函数接受{ intrinsics: 'inherit' }
作为参数以后,就会继承原始顶层对象的方法。
用户可以自己定义的子类,用来定制自己的沙箱。
class FakeWindow extends Realm {
init() {
super.init();
global.document = new FakeDocument(...);
global.alert = new Proxy(fakeAlert, { ... });
// ...
}
上面代码中,FakeWindow
模拟了一个假的顶层对象。