Kontynuacja poprzednich lekcji, robimy podobne rzeczy, tym razem z local storage – do dzieła.
Ok, najpierw napiszemy polyfill dla hasItem:
window.localStorage.hasItem = function(key){
return localStorage.getItem(key !== null);
};
W sumie to nie żaden polyfill, tylko coś, czego nie ma a być powinno. Dobra, teraz funkcja-konstruktor:
function LocalStorageVariable(name, value=null){
this.name = name;
this.exists = true;
if(value === null){
if(localStorage.hasItem(name)){
this.value = localStorage.getItem(name);
} else {
this.value = 0;
localStorage.setItem(name, 0);
}
} else {
this.value = value;
localStorage.setItem(name, value);
}
}
Strasznie trudne to chyba nie jest, parę rzeczy wziąłem pod uwagę, np. że coś już istnieje, albo tworzymy tylko nazwę, bez wartości.
Dobra, drobne funkcje pomocnicze:
LocalStorageVariable.prototype.clearValue = function(){
localStorage.setItem(this.name, 0);
this.value = 0;
};
LocalStorageVariable.prototype.remove = function(){
localStorage.removeItem(this.name);
this.exists = false;
}
Teraz nasz handler:
const lsvarHandler = {
set(obj, prop, value){
if(prop !== 'value')
return Reflect.set(...arguments);
obj.value = value;
localStorage.setItem(obj.name, value);
return;
},
To już powinniśmy znać. Ok, teraz get:
get(target, prop, receiver){
if(typeof target[prop] === 'function'){
return target[prop]();
}
if(target.exists === false)
return;
localStorage.setItem(target.name, target.value);
return target.value;
}
}
Z getem o tyle ciekawa sprawa, że można na nim wołać metody, ale musimy zapomnieć o nawiasach. Niby są inne opcje, choćby apply i call traps, albo zwracanie binda jako funkcji do używania.
Na razie te nasze funkcyjki nie używają żadnych argumentów i można tak się pobawić. Bo idea jest taka, że nie chcemy dawać użytkownikowi lsVar i lsProxy i część zabawy masz z lsVar a część z lsProxy.
Pomyślimy, co tu zrobić, może wrapper jakiś, tym niemniej na razie taki to właśnie śmieszny myk poznaliśmy.
Ok, użycie:
let lsProxy = new Proxy(lsvar, lsvarHandler);
console.log(lsProxy.value);
lsProxy.value = "Jane Doe";
console.log(lsProxy.value);
Możemy też zrobić:
lsVar.clearValue();
Albo:
lsProxy.clearValue;
Generalnie wszystko jest synchronizowane i działa dobrze. Podwaliny pod to, co chcemy napisać…