Last active
June 28, 2018 12:28
-
-
Save c7x43t/0de14c372d055275f3273454bc086ee8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(global) { | |
var PARENT = "[[__PARENT__]]"; | |
function Immutable(obj) { | |
if (obj instanceof Object) { | |
for (var keys = Object.keys(obj), i = 0; i < keys.length; i++) { | |
this[keys[i]] = obj[keys[i]]; | |
} | |
} | |
if (obj !== false) Object.freeze(this); | |
return this; | |
} | |
Immutable.prototype.get = function(key) { | |
return this.getIn(key); | |
}; | |
Immutable.prototype.getIn = function(key) { | |
var tmp, obj = this; | |
if (key instanceof Array) { | |
for (var i = 0, lastIndex = key.length - 1; i < key.length; i++) { | |
while (true) { | |
tmp = obj[key[i]]; | |
//console.log({tmp:tmp,last:i===lastIndex,obj:obj,parent:obj.hasOwnProperty(PARENT)}) | |
if (tmp !== undefined || !obj.hasOwnProperty(PARENT)) { | |
if (i === lastIndex) { | |
return tmp; | |
} else { | |
i++; | |
obj = tmp; | |
} | |
} else { | |
obj = obj[PARENT]; | |
} | |
} | |
} | |
} else { | |
return this.getIn([key]); | |
} | |
}; | |
Immutable.prototype.set = function(key, value, parent) { | |
var tmp = new Immutable(false); | |
tmp[key] = value; | |
//if(parent===undefined) | |
tmp[PARENT] = this; | |
Object.freeze(tmp); | |
return tmp; | |
}; | |
Immutable.prototype.setIn = function(key, value, parent) { | |
if (key instanceof Array && key.length > 1) { | |
var tmpKey = [key.shift()]; | |
var tmpNext = this.getIn(tmpKey); | |
var isImmutable = tmpNext instanceof this.constructor; | |
var next = isImmutable ? tmpNext : new this.constructor(tmpNext); | |
return this.set(tmpKey, next.setIn(key, value, isImmutable ? isImmutable : undefined), parent); | |
} else { | |
return this.set(key, value, parent); | |
} | |
}; | |
global.Immutable = Immutable; | |
}(window)); | |
//var imm=new Immutable({a:{b:{c:3}}}); | |
//imm.setIn(["a","b","c"],4); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(global) { | |
var NOOP = () => {}; | |
var PARENT = "[[__PARENT__]]"; | |
function Immutable(obj) { | |
if (obj === undefined) return this; | |
for (var keys = Object.keys(obj), i = 0; i < keys.length; i++) { | |
this[keys[i]] = obj[keys[i]]; | |
} | |
} | |
Immutable.prototype.get = function(key) { | |
if (key instanceof Array) { | |
return this.getIn(key); | |
} | |
var tmp, obj = this; | |
while (true) { | |
tmp = obj[key]; | |
if (tmp || !obj.hasOwnProperty[PARENT]) { | |
return tmp; | |
} else { | |
obj = obj[PARENT]; | |
} | |
} | |
}; | |
// tailEndRecursionHashFunction: | |
function getHashFunction(object, keys, keyLength) { | |
var tmp = getHashed[keyLength - 1](object, keys, keyLength - 1); | |
return tmp.hasOwnProperty("get") ? tmp.get(keys[1]) : tmp[keys[1]]; | |
} | |
var getHashed = new Array(20).fill(getHashFunction); | |
getHashed[0] = NOOP; | |
getHashed[1] = (object, keys) => object.get(keys[0]); | |
Immutable.prototype.getIn = function(key) { | |
return getHashed[key.length](this, key, key.length); | |
} | |
Immutable.prototype.set = function(key, value) { | |
var tmp = new Immutable(); | |
tmp[key] = value; | |
tmp[PARENT] = this; | |
Object.freeze(tmp); | |
return tmp; | |
}; | |
global.Immutable = Immutable; | |
}(window)); | |
var value = Math.random(); | |
var cycles = 5e6; | |
var time = performance.now(); | |
var obj = new Immutable({ | |
value | |
}); | |
for (let i = 0; i < cycles; i++) { | |
const val = obj.get("value"); | |
} | |
console.log({ | |
get: performance.now() - time | |
}); | |
//_________________________________ | |
var value = Math.random(); | |
var cycles = 5e6; | |
var time = performance.now(); | |
var obj = new Immutable({ | |
value | |
}); | |
for (let i = 0; i < cycles; i++) { | |
const newValue = Math.random(); | |
const val = obj.set("value", newValue); | |
} | |
console.log({ | |
set: performance.now() - time | |
}); | |
//_________________________________ | |
var value = { | |
a: Math.random() | |
}; | |
var cycles = 5e6; | |
var time = performance.now(); | |
var obj = new Immutable({ | |
value | |
}); | |
for (let i = 0; i < cycles; i++) { | |
const val = obj.getIn(["value", "a"]); | |
} | |
console.log({ | |
getIn: performance.now() - time | |
}); | |
//_________________________________ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// mock Immutable | |
function Immutable(obj){ | |
var self=this; | |
function get(key){ | |
return self[key]; | |
}; | |
function set(key,value){ | |
return self[key]=value; | |
}; | |
function isObject(obj){ | |
return obj&&obj.constructor === Object; | |
} | |
if(!isObject(obj)){ | |
obj={}; | |
} | |
Object.defineProperty(obj,"get",{value:get}); | |
Object.defineProperty(obj,"set",{value:set}); | |
return obj; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var immutableHandler={ | |
get: function(obj,key){ | |
return obj.hasOwnProperty(key)?obj[key]:obj.hasOwnProperty("__Parent__")?obj.__Parent__[key]:undefined; | |
}, | |
has: function(obj,key){ | |
return obj.__Keys__.has(key) | |
} | |
} | |
function Immutable(obj){ | |
//var clone={...obj}; | |
var keys=new Set(Object.keys(obj)); | |
var clone=Object.assign({},obj); | |
Object.defineProperty(clone,"__Keys__",{value:keys}); | |
var proxy = new Proxy(clone, immutableHandler); | |
Object.freeze(makeIterable(proxy)); | |
return proxy; | |
} | |
function NOOP(){} | |
function objectSubclass(obj){ | |
var subObj={}; | |
function collector(){}; | |
for(var key of obj.__Keys__){ | |
collector.prototype[key]=NOOP; | |
} | |
Object.setPrototypeOf(subObj,collector.prototype); | |
//collector.prototype=Object.create(Object.prototype); | |
return subObj; | |
} | |
function set(obj,key,value){ | |
var newObj={}; | |
function collector(){}; | |
for(var key of obj.__Keys__){ | |
collector.prototype[key]=NOOP; | |
} | |
Object.setPrototypeOf(newObj,collector.prototype); | |
//var newObj=new objectSubclass(obj); | |
var keys = new Set(obj.__Keys__); | |
keys.add(key+""); | |
Object.defineProperty(newObj,"__Keys__",{value:keys}); | |
Object.defineProperty(newObj,"__Parent__",{value:obj}); | |
newObj[key]=value; | |
var proxy=new Proxy(newObj, immutableHandler); | |
Object.freeze(makeIterable(proxy)); | |
return proxy; | |
} | |
function makeIterable(imm){ | |
imm[Symbol.iterator]=function*(){ | |
for(var key of imm.__Keys__){ | |
yield imm[key]; | |
} | |
} | |
return imm; | |
} | |
var target={a:3}; | |
var p = Immutable(target); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment