UNPKG

es-map

Version:

An ES-spec-compliant Map shim/polyfill/replacement that works as far down as ES3

89 lines (77 loc) 2.86 kB
'use strict'; var hasSymbols = require('has-symbols')(); var GetIntrinsic = require('get-intrinsic'); var SLOT = require('internal-slot'); var entries = require('object.entries'); var forEach = require('for-each'); var DefineMethodProperty = require('es-abstract/2024/DefineMethodProperty'); var OrdinaryObjectCreate = require('es-abstract/2024/OrdinaryObjectCreate'); var Type = require('es-abstract/2024/Type'); var $ObjectCreate = GetIntrinsic('%Object.create%', true); var hasProto = require('has-proto')(); exports.emptyObject = function () { if ($ObjectCreate) { return $ObjectCreate(null); } if (hasProto) { return { __proto__: null }; } return {}; }; // eslint-disable-next-line max-params exports.emulateES6construct = function (o, defaultNewTarget, defaultProto, slots) { /* * This is an es5 approximation to es6 construct semantics. in es6, * 'new Foo' invokes Foo.[[Construct]] which (for almost all objects) * just sets the internal variable NewTarget (in es6 syntax `new.target`) * to Foo and then returns Foo(). */ /* * Many ES6 object then have constructors of the form: * 1. If NewTarget is undefined, throw a TypeError exception * 2. Let xxx by OrdinaryCreateFromConstructor(NewTarget, yyy, zzz) */ // So we're going to emulate those first two steps. if (Type(o) !== 'Object') { throw new TypeError('Constructor requires `new`: ' + defaultNewTarget.name); } var proto = defaultNewTarget.prototype; if (Type(proto) !== 'Object') { proto = defaultProto; } var obj = OrdinaryObjectCreate(proto); forEach(entries(slots), function (entry) { var key = entry[0]; var value = entry[1]; SLOT.set(obj, key, value); }); return obj; }; /* * This is a private name in the es6 spec, equal to '[Symbol.iterator]' * we're going to use an arbitrary _-prefixed name to make our shims * work properly with each other, even though we don't have full Iterator * support. That is, `Array.from(map.keys())` will work, but we don't * pretend to export a "real" Iterator interface. */ var $iterator$ = hasSymbols && typeof Symbol.iterator === 'symbol' ? Symbol.iterator : '_es6-shim iterator_'; /* * Firefox ships a partial implementation using the name @@iterator. * https://bugzilla.mozilla.org/show_bug.cgi?id=907077#c14 * So use that name if we detect it. */ if (typeof []['@@iterator'] === 'function') { $iterator$ = '@@iterator'; } exports.addIterator = function (prototype, impl) { var implementation = impl || function iterator() { // eslint-disable-next-line no-invalid-this return this; }; DefineMethodProperty(prototype, $iterator$, implementation, false); if (!prototype[$iterator$] && typeof $iterator$ === 'symbol') { // implementations are buggy when $iterator$ is a Symbol // eslint-disable-next-line no-param-reassign prototype[$iterator$] = implementation; } };