Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function createImmutable(item){
- let handler = {
- set: function(target, property, value){
- //do nothing, this object is no longer "directly" mutable
- console.log("hey, I'm immutable, you can't set me like this");
- },
- //object is mutable only by invoking a "set_XXXX" method
- //we trap that get and return a function that will create the new object with the mutated property
- //and returns a proxy around the new object, so that immutability continues to work in ensuing assignments
- get: function(target, property, receiver){
- if (property.startsWith("set_")){
- let propName = property.substring(4);
- console.log("assigning to " + propName + " via proxy");
- return function(value){
- //either use the trapped target or "this"
- //let newItem = new target.constructor();
- let newItem = new this.constructor();
- Object.assign(newItem, target);
- //notice I've just doing shallow cloning
- newItem[propName] = value;
- return new Proxy(newItem, handler);
- }
- }
- else{
- return target[property];
- }
- }
- };
- return new Proxy(item, handler);
- }
- //Let's test it
- class Person{
- constructor(name){
- this.name = name;
- }
- say(word){
- return `${word}, I'm ${this.name}`;
- }
- }
- //--- Main
- console.log("started");
- let p1 = new Person("Francois");
- console.log("p1 says: " + p1.say("hi"));
- let immutableP1 = createImmutable(p1);
- console.log("immutableP1" + JSON.stringify(immutableP1));
- immutableP1.name = "Xuan";
- console.log("immutableP1" + JSON.stringify(immutableP1));
- let immutableP2 = immutableP1.set_name("Xuan");
- console.log("immutableP2" + JSON.stringify(immutableP2));
- console.log(immutableP2.say("hi"));
- let immutableP3 = immutableP2.set_name("Emmanuel");
- console.log("immutableP3" + JSON.stringify(immutableP3));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement