es.array.concat.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. 'use strict';
  2. var $ = require('../internals/export');
  3. var fails = require('../internals/fails');
  4. var isArray = require('../internals/is-array');
  5. var isObject = require('../internals/is-object');
  6. var toObject = require('../internals/to-object');
  7. var toLength = require('../internals/to-length');
  8. var createProperty = require('../internals/create-property');
  9. var arraySpeciesCreate = require('../internals/array-species-create');
  10. var arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');
  11. var wellKnownSymbol = require('../internals/well-known-symbol');
  12. var V8_VERSION = require('../internals/engine-v8-version');
  13. var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');
  14. var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
  15. var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';
  16. // We can't use this feature detection in V8 since it causes
  17. // deoptimization and serious performance degradation
  18. // https://github.com/zloirock/core-js/issues/679
  19. var IS_CONCAT_SPREADABLE_SUPPORT = V8_VERSION >= 51 || !fails(function () {
  20. var array = [];
  21. array[IS_CONCAT_SPREADABLE] = false;
  22. return array.concat()[0] !== array;
  23. });
  24. var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
  25. var isConcatSpreadable = function (O) {
  26. if (!isObject(O)) return false;
  27. var spreadable = O[IS_CONCAT_SPREADABLE];
  28. return spreadable !== undefined ? !!spreadable : isArray(O);
  29. };
  30. var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
  31. // `Array.prototype.concat` method
  32. // https://tc39.github.io/ecma262/#sec-array.prototype.concat
  33. // with adding support of @@isConcatSpreadable and @@species
  34. $({ target: 'Array', proto: true, forced: FORCED }, {
  35. concat: function concat(arg) { // eslint-disable-line no-unused-vars
  36. var O = toObject(this);
  37. var A = arraySpeciesCreate(O, 0);
  38. var n = 0;
  39. var i, k, length, len, E;
  40. for (i = -1, length = arguments.length; i < length; i++) {
  41. E = i === -1 ? O : arguments[i];
  42. if (isConcatSpreadable(E)) {
  43. len = toLength(E.length);
  44. if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
  45. for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
  46. } else {
  47. if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
  48. createProperty(A, n++, E);
  49. }
  50. }
  51. A.length = n;
  52. return A;
  53. }
  54. });