模拟javaScript 沙箱原理 (快照沙箱 与 proxy 代理沙箱)(微前端乾坤框架)

原理很简单 , 主要是编码思想,需要借鉴, 多多思考

快照沙箱实现 原理

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>模拟js快照沙箱</title>
</head>

<body>
  <script>
    class SnapshotSandbox {
      constructor(window) {
        this.proxy = window;   //将proxy 赋值为window
        this.modifyPropMap = {}  // 记录在window上的修改
        this.active(); // 默认激活状态 
      }
      // 激活沙箱
      active() {
        // 声明一个变量用来保存 拍照(给window拍个照也就是保存一下没有改变之前window有哪些私有属性)
        this.windowSnapshot = {}
        // 循环window上面的属性赋值给windowSnapshot
        for (const prop in this.proxy) {
          if (this.proxy.hasOwnProperty(prop)) {
            this.windowSnapshot[prop] = this.proxy[prop];
          }
        }
        // 将保存的属性添加到上面
        Object.keys(this.modifyPropMap).forEach(item => {
          this.proxy[item] = this.modifyPropMap[item]
        })
      }
      // 沙箱失活
      inactive() {
        for (const prop in this.proxy) {
          if (this.proxy.hasOwnProperty(prop)) {
            // 如果符合这个条件就代表这个属性变化了
            if (this.proxy[prop] !== this.windowSnapshot[prop]) {
              //  于是就需要将这个属性保存起来
              this.modifyPropMap[prop] = this.proxy[prop]
              // 将这个变化的属性还原成之前的值
              this.proxy[prop] = this.windowSnapshot[prop]
            }
          }
        }
      }

    }
    // 使用 
    let sandbox = new SnapshotSandbox(window)
      ; ((window) => {
        // 加两个属性
        window.a = 1
        window.b = 2
        console.log(window.a, window.b); // 1,2
        sandbox.inactive() // 失去属性
        console.log(window.a, window.b); // undefined undefined
        sandbox.active()  // 还原属性
        console.log(window.a, window.b); // 1 ,2
      })(sandbox.proxy)
  </script>
</body>

</html>

Proxy 代理沙箱 实现 原理

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>proxy代理沙箱</title>
</head>

<body>
  <script>
    // 实现Proxy沙箱
    class ProxyShaBox {
      constructor() {
        // 全局属性
        const windowSX = window
        // 保存这用户更改的属性(变化存储库)
        const changeParam = {}
        // 个人感觉有点像工厂模式  new 一个 新的proxy实例
        this.proxy = new Proxy(changeParam, {
          set(tarObj, attr, value) {
            tarObj[attr] = value
            return true
          },
          get(tarObj, attr) {
            // 如果 变化存储库里面有 就用里面的, 如果没有就用全局的属性
            return tarObj[attr] || windowSX[attr]
          }
        })
      }
    }

    let proxySx1 = new ProxyShaBox()
    let proxySx2 = new ProxyShaBox()
      ; ((window) => {
        window.a = 10
        console.log(window.a);
      })(proxySx1.proxy)

      ; ((window) => {
        window.a = 20
        console.log(window.a);
      })(proxySx2.proxy)
  </script>
</body>

</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值