Last active
August 5, 2017 17:22
-
-
Save Slayer95/69a80b791f557cf13cc63ccba04e2658 to your computer and use it in GitHub Desktop.
Set shallow clone
This file contains 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
const assert = require('assert'); | |
const fs = require('fs'); | |
const vm = require('vm'); | |
const iterateSetElems = set => Set.prototype.keys.call(set); | |
const Builtin = require('proposal-istypes/polyfill'); // Git dependency | |
const SetPolyfillSource = fs.readFileSync(require.resolve('es6-shim'), 'utf8'); | |
// Get a good polyfill for Set. | |
// We achieve this by loading the Set implementation from es6-shim. | |
// es6-shim doesn't support @@builtin, so we add it on top. | |
const vmCtx = (() => { | |
const sandboxGlobal = { | |
require: require, SYMBOL_BUILTIN: Symbol.builtin, module: {exports: {}}, | |
Set: class BrokenSet {add() {} has() {} delete() {}}, // Required to convince es6-shim to implement its Set polyfill. | |
}; | |
sandboxGlobal.global = sandboxGlobal; | |
sandboxGlobal.exports = sandboxGlobal.module.exports; | |
const ctx = vm.createContext(sandboxGlobal); | |
vm.runInContext(SetPolyfillSource, ctx); | |
vm.runInContext(`this.Set[SYMBOL_BUILTIN] = () => 'Set';`, ctx); // Implement Set@@builtin | |
return ctx; | |
})(); | |
const cloneMethods = { | |
'Set': function cloneSet(source) { | |
return new Set(iterateSetElems(source)); | |
}, | |
}; | |
function shallowClone(base) { | |
if (base === null || typeof base !== 'object') return base; | |
const type = Builtin.typeOf(base); | |
const clone = type in cloneMethods ? cloneMethods[type](base) : Object.create(Object.getPrototypeOf(base)); | |
Object.defineProperties(clone, Object.getOwnPropertyDescriptors(base)); | |
return clone; | |
} | |
const realSet = new Set([1, 2]); | |
vm.runInContext(` | |
this.result = new Set([1, 2]); | |
`, vmCtx); | |
const polySet = vmCtx.result; | |
assert(realSet.has(1)); | |
assert(shallowClone(realSet).has(1)); | |
assert(polySet.has(1)); | |
assert(shallowClone(polySet).has(1)); // TypeError exception @shallowClone |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment