JS沙箱機(jī)制

一.思考

微前端應(yīng)用加載 剛開(kāi)始我加載A應(yīng)用 window.a B應(yīng)用 window.a 怎樣可以倆個(gè)應(yīng)用里的a屬性互不影響

二.什么是沙箱

①應(yīng)用的運(yùn)行 從開(kāi)始到結(jié)束 切換后不會(huì)影響全局
②創(chuàng)造一個(gè)干凈的環(huán)境給這個(gè)子應(yīng)用使用,當(dāng)切換時(shí),可以選擇丟棄屬性和恢復(fù)屬性

三.實(shí)現(xiàn)

單應(yīng)用切換 JS沙箱 乾坤的倆種機(jī)制

①快照沙箱

舉例 : 比如想看你變沒(méi)變樣 一年前拍一張 再拍一張 (將區(qū)別保存起來(lái)) 在回到一年前 相當(dāng)于這一年干了很多事 等會(huì)要是想還原 就可以把區(qū)別在應(yīng)用到這一年
核心:前后比對(duì),把區(qū)別保存起來(lái),在回到以前,如果想在恢復(fù)這個(gè)沙箱就把剛才的區(qū)別運(yùn)行回來(lái)

缺點(diǎn): 如果是多個(gè)子應(yīng)用就不能使用這種方式了,可以完全使用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];
            }
        }
        // 將上次的修改進(jìn)行一個(gè)應(yīng)用 到 當(dāng)前的window上
        Object.keys(this.modifyPropsMap).forEach(p => {
            // 將上次修改過(guò)得賦到window上
            window[p] = this.modifyPropsMap[p];
        })
    }

    // 丟棄沙箱
    inactve() {
        for (const prop in window) {
            if (window.hasOwnProperty(prop)) {
                if (window[prop] !== this.windowSnapshot[prop]) {
                    // 拿現(xiàn)在的和一年前的作比較 如果他倆不一樣了 說(shuō)明換這個(gè)屬性有變化 有變化就把變化記錄在變化表里
                    this.modifyPropsMap[prop] = window[prop]
                    // 最后在將window變回一年前
                    window[prop] = this.windowSnapshot[prop]
                }
            }
        }
    }
}

let sandbox = new SanpshotSandbox();

//通過(guò)沙箱返回一個(gè)代理
((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倆個(gè)盒子 這倆個(gè)盒子傳入的屬性并不是window 取值的時(shí)候先會(huì)取代理的window 取不到才會(huì)取原window 這種方案不會(huì)影響全局window

優(yōu)點(diǎn):可以實(shí)現(xiàn)多應(yīng)用沙箱 把不同的應(yīng)用用不同的代理來(lái)處理
缺點(diǎn):但是有些瀏覽器不支持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); 

四.對(duì)比

倆種情況 ①父應(yīng)用和子應(yīng)用 ②多應(yīng)用


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 自己實(shí)現(xiàn)一個(gè)快照沙箱:1 年前拍一張,再拍一張,將區(qū)別保存起來(lái),再回到一年前,多個(gè)子應(yīng)用就不能使用這種方式了,可以...
    IOneStar閱讀 963評(píng)論 0 1
  • css隔離方案 子應(yīng)用之間樣式隔離Dynamic Stylesheet 動(dòng)態(tài)樣式表,當(dāng)應(yīng)用切換時(shí)移除老應(yīng)用樣式,添...
    我是小布丁閱讀 1,213評(píng)論 0 1
  • 前言 在做微前端的時(shí)候,有時(shí)候會(huì)遇到不同版本的問(wèn)題。但是加載的js 又不能污染全局,只能在對(duì)應(yīng)的scope中生存。...
    黑曼巴yk閱讀 133評(píng)論 0 0
  • 當(dāng)學(xué)習(xí)成為了習(xí)慣,知識(shí)也就變成了常識(shí)。感謝各位的 點(diǎn)贊、收藏和評(píng)論。 新視頻和文章會(huì)第一時(shí)間在微信公眾號(hào)發(fā)送,歡迎...
    李永寧_lyn閱讀 713評(píng)論 0 0
  • 1:如何配置進(jìn)行控制 registerMicroApps方法里面調(diào)用loadApp會(huì)傳入frameworkConf...
    flyrain2020閱讀 8,928評(píng)論 1 7

友情鏈接更多精彩內(nèi)容