es.array.concat.js 2.5 KB

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