Skip to content

Instantly share code, notes, and snippets.

@Slayer95
Last active August 5, 2017 17:22
Show Gist options
  • Save Slayer95/69a80b791f557cf13cc63ccba04e2658 to your computer and use it in GitHub Desktop.
Save Slayer95/69a80b791f557cf13cc63ccba04e2658 to your computer and use it in GitHub Desktop.
Set shallow clone
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