UNPKG

4.19 kBJavaScriptView Raw
1'use strict';
2var $ = require('../internals/export');
3var global = require('../internals/global');
4var isForced = require('../internals/is-forced');
5var redefine = require('../internals/redefine');
6var InternalMetadataModule = require('../internals/internal-metadata');
7var iterate = require('../internals/iterate');
8var anInstance = require('../internals/an-instance');
9var isObject = require('../internals/is-object');
10var fails = require('../internals/fails');
11var checkCorrectnessOfIteration = require('../internals/check-correctness-of-iteration');
12var setToStringTag = require('../internals/set-to-string-tag');
13var inheritIfRequired = require('../internals/inherit-if-required');
14
15module.exports = function (CONSTRUCTOR_NAME, wrapper, common, IS_MAP, IS_WEAK) {
16 var NativeConstructor = global[CONSTRUCTOR_NAME];
17 var NativePrototype = NativeConstructor && NativeConstructor.prototype;
18 var Constructor = NativeConstructor;
19 var ADDER = IS_MAP ? 'set' : 'add';
20 var exported = {};
21
22 var fixMethod = function (KEY) {
23 var nativeMethod = NativePrototype[KEY];
24 redefine(NativePrototype, KEY,
25 KEY == 'add' ? function add(value) {
26 nativeMethod.call(this, value === 0 ? 0 : value);
27 return this;
28 } : KEY == 'delete' ? function (key) {
29 return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);
30 } : KEY == 'get' ? function get(key) {
31 return IS_WEAK && !isObject(key) ? undefined : nativeMethod.call(this, key === 0 ? 0 : key);
32 } : KEY == 'has' ? function has(key) {
33 return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);
34 } : function set(key, value) {
35 nativeMethod.call(this, key === 0 ? 0 : key, value);
36 return this;
37 }
38 );
39 };
40
41 // eslint-disable-next-line max-len
42 if (isForced(CONSTRUCTOR_NAME, typeof NativeConstructor != 'function' || !(IS_WEAK || NativePrototype.forEach && !fails(function () {
43 new NativeConstructor().entries().next();
44 })))) {
45 // create collection constructor
46 Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER);
47 InternalMetadataModule.REQUIRED = true;
48 } else if (isForced(CONSTRUCTOR_NAME, true)) {
49 var instance = new Constructor();
50 // early implementations not supports chaining
51 var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
52 // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false
53 var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });
54 // most early implementations doesn't supports iterables, most modern - not close it correctly
55 // eslint-disable-next-line no-new
56 var ACCEPT_ITERABLES = checkCorrectnessOfIteration(function (iterable) { new NativeConstructor(iterable); });
57 // for early implementations -0 and +0 not the same
58 var BUGGY_ZERO = !IS_WEAK && fails(function () {
59 // V8 ~ Chromium 42- fails only with 5+ elements
60 var $instance = new NativeConstructor();
61 var index = 5;
62 while (index--) $instance[ADDER](index, index);
63 return !$instance.has(-0);
64 });
65
66 if (!ACCEPT_ITERABLES) {
67 Constructor = wrapper(function (dummy, iterable) {
68 anInstance(dummy, Constructor, CONSTRUCTOR_NAME);
69 var that = inheritIfRequired(new NativeConstructor(), dummy, Constructor);
70 if (iterable != undefined) iterate(iterable, that[ADDER], that, IS_MAP);
71 return that;
72 });
73 Constructor.prototype = NativePrototype;
74 NativePrototype.constructor = Constructor;
75 }
76
77 if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
78 fixMethod('delete');
79 fixMethod('has');
80 IS_MAP && fixMethod('get');
81 }
82
83 if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
84
85 // weak collections should not contains .clear method
86 if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear;
87 }
88
89 exported[CONSTRUCTOR_NAME] = Constructor;
90 $({ global: true, forced: Constructor != NativeConstructor }, exported);
91
92 setToStringTag(Constructor, CONSTRUCTOR_NAME);
93
94 if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP);
95
96 return Constructor;
97};