1'use strict'; 2var global = require('./_global'); 3var $export = require('./_export'); 4var redefine = require('./_redefine'); 5var redefineAll = require('./_redefine-all'); 6var meta = require('./_meta'); 7var forOf = require('./_for-of'); 8var anInstance = require('./_an-instance'); 9var isObject = require('./_is-object'); 10var fails = require('./_fails'); 11var $iterDetect = require('./_iter-detect'); 12var setToStringTag = require('./_set-to-string-tag'); 13var inheritIfRequired = require('./_inherit-if-required'); 14 15module.exports = function (NAME, wrapper, methods, common, IS_MAP, IS_WEAK) { 16 var Base = global[NAME]; 17 var C = Base; 18 var ADDER = IS_MAP ? 'set' : 'add'; 19 var proto = C && C.prototype; 20 var O = {}; 21 var fixMethod = function (KEY) { 22 var fn = proto[KEY]; 23 redefine(proto, KEY, 24 KEY == 'delete' ? function (a) { 25 return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); 26 } : KEY == 'has' ? function has(a) { 27 return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); 28 } : KEY == 'get' ? function get(a) { 29 return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a); 30 } : KEY == 'add' ? function add(a) { fn.call(this, a === 0 ? 0 : a); return this; } 31 : function set(a, b) { fn.call(this, a === 0 ? 0 : a, b); return this; } 32 ); 33 }; 34 if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function () { 35 new C().entries().next(); 36 }))) { 37 // create collection constructor 38 C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER); 39 redefineAll(C.prototype, methods); 40 meta.NEED = true; 41 } else { 42 var instance = new C(); 43 // early implementations not supports chaining 44 var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance; 45 // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false 46 var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); }); 47 // most early implementations doesn't supports iterables, most modern - not close it correctly 48 var ACCEPT_ITERABLES = $iterDetect(function (iter) { new C(iter); }); // eslint-disable-line no-new 49 // for early implementations -0 and +0 not the same 50 var BUGGY_ZERO = !IS_WEAK && fails(function () { 51 // V8 ~ Chromium 42- fails only with 5+ elements 52 var $instance = new C(); 53 var index = 5; 54 while (index--) $instance[ADDER](index, index); 55 return !$instance.has(-0); 56 }); 57 if (!ACCEPT_ITERABLES) { 58 C = wrapper(function (target, iterable) { 59 anInstance(target, C, NAME); 60 var that = inheritIfRequired(new Base(), target, C); 61 if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that); 62 return that; 63 }); 64 C.prototype = proto; 65 proto.constructor = C; 66 } 67 if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) { 68 fixMethod('delete'); 69 fixMethod('has'); 70 IS_MAP && fixMethod('get'); 71 } 72 if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER); 73 // weak collections should not contains .clear method 74 if (IS_WEAK && proto.clear) delete proto.clear; 75 } 76 77 setToStringTag(C, NAME); 78 79 O[NAME] = C; 80 $export($export.G + $export.W + $export.F * (C != Base), O); 81 82 if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP); 83 84 return C; 85}; 86