一.思考
微前端應(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