js css html

JS沙箱机制

2022-04-12  本文已影响0人  e只咸鱼

一.思考

微前端应用加载 刚开始我加载A应用 window.a B应用 window.a 怎样可以俩个应用里的a属性互不影响

二.什么是沙箱

①应用的运行 从开始到结束 切换后不会影响全局
②创造一个干净的环境给这个子应用使用,当切换时,可以选择丢弃属性和恢复属性

三.实现

单应用切换 JS沙箱 乾坤的俩种机制

①快照沙箱

举例 : 比如想看你变没变样 一年前拍一张 再拍一张 (将区别保存起来) 在回到一年前 相当于这一年干了很多事 等会要是想还原 就可以把区别在应用到这一年
核心:前后比对,把区别保存起来,在回到以前,如果想在恢复这个沙箱就把刚才的区别运行回来

缺点: 如果是多个子应用就不能使用这种方式了,可以完全使用es6 proxy

class SanpshotSandbox {
    constructor() {
        this.proxy = window; //window属性
        this.modifyPropsMap = {} //记录在window上的修改
        this.active();
    }

    // 激活沙箱
    active() {
        this.windowSnapshot = {}; //拍照
        for (const prop in window) {
            if (window.hasOwnProperty(prop)) {
                this.windowSnapshot[prop] = window[prop];
            }
        }
        // 将上次的修改进行一个应用 到 当前的window上
        Object.keys(this.modifyPropsMap).forEach(p => {
            // 将上次修改过得赋到window上
            window[p] = this.modifyPropsMap[p];
        })
    }

    // 丢弃沙箱
    inactve() {
        for (const prop in window) {
            if (window.hasOwnProperty(prop)) {
                if (window[prop] !== this.windowSnapshot[prop]) {
                    // 拿现在的和一年前的作比较 如果他俩不一样了 说明换这个属性有变化 有变化就把变化记录在变化表里
                    this.modifyPropsMap[prop] = window[prop]
                    // 最后在将window变回一年前
                    window[prop] = this.windowSnapshot[prop]
                }
            }
        }
    }
}

let sandbox = new SanpshotSandbox();

//通过沙箱返回一个代理
((window) => {
    window.a = 1;
    window.b = 2;
    console.log(window.a, window.b); // 1  2
    sandbox.inactve(); //失去激活后
    console.log(window.a, window.b); // undefined  undefined
    sandbox.actve(); //激活
    console.log(window.a, window.b);  // 1  2
})(sandbox.proxy); //sandbox.proxy就是window

②proxy沙箱

原理 :new俩个盒子 这俩个盒子传入的属性并不是window 取值的时候先会取代理的window 取不到才会取原window 这种方案不会影响全局window

优点:可以实现多应用沙箱 把不同的应用用不同的代理来处理
缺点:但是有些浏览器不支持proxy使用

class ProxySandbox {
    constructor(){
        const rawWindow = window;
        const fakeWindow = {};
        const proxy = new Proxy(fakeWindow,{
            set(target,p,value){
                target[p] = value;
                return true
            },
            get(target,p){
                return target[p] || fakeWindow[p];
            }
        });
        this.proxy = proxy;
    }
}

let sandbox1 = new ProxySandbox();
let sandbox2 = new ProxySandbox();
window.a = 1;
((window) => {
    window.a = 'hello';
    console.log(window.a); 
})(sandbox1.proxy); 
((window) => {
    window.a = 'hello';
    console.log(window.a); 
})(sandbox2.proxy); 

四.对比

俩种情况 ①父应用和子应用 ②多应用


image.png
上一篇 下一篇

猜你喜欢

热点阅读