最近手头我的项目利用到了沙箱机制顺便钻研了下 间接上代码~

function sandbox(code) {    code= 'with (sandbox) {' + code + '}'    return new Function('sandbox', code)}let str = 'let a = 10;console.log(a)'sandbox(str)({})//而es6的proxy则能够解决这个问题,proxy能够设置拜访拦截器,于是with再加上proxy简直完满解决js沙箱机制。当然,还是有机制能够绕过,有大神发现Symbol.unScopables能够不受with的影响,所以要另外解决Symbol.unScopables:
class ProxySandbox{  constructor(){    const rawWindow = window    const fakeWindow = {}    const proxy = new Proxy(fakeWindow, {      set(target,prop,value){        target[prop] = value        return true      },      get(target,prop){        return target[prop] || fakeWindow[prop]      }    })    this.proxy = proxy  }}const sandbox1 = new ProxySandbox()const sandbox2 = new ProxySandbox()window.a = 1((window) => {  window.a = 'hello'  console.log(window.a)})(sandbox1.proxy)((window) => {  window.a = 'world'  console.log(window.a)})(sandbox1.proxy)

下面的例子利用到es6的proxy,目前js沙箱能做到的最好的沙箱机制,实用于多个利用,然而也有兼容性的限度

快照沙箱

class snapShotSandbox{  proxy = window // window 属性  modifyPropsMap = {} // 记录在window上的批改  active()  active(){ // 激活沙箱    this.windowSnapshot = {} // 拍照    for(const prop in window){      if(window.hasOwnProperty(prop)){        this.windowSnapshot[prop] = window[prop]      }    }    Object.keys(this.modifyPropsMap).forEach(prop => {      window[prop] = this.modifyPropsMap[prop]    })  }  inactive(){ // 失活沙箱    for(const prop in window){      if(window.hasOwnProperty(prop)){        if(window[prop] !== this.windowSnapshot[prop]){          this.modifyPropsMap[prop] = window[prop]          window[prop] = this.windowSnapshot[prop]        }      }    }  }}const sandbox = new snapShotSandbox() ((window) => {  window.a = 1  window.b = 2  console.log(window.a, window.b)  sandbox.inactive()  console.log(window.a, window.b)  sandbox.active()  console.log(window.a, window.b)})(sandbox.proxy) // sandbox.proxy 就是 window

// 不反对多个子利用