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 lengthOfArrayLike = require('../internals/length-of-array-like');
  8. var doesNotExceedSafeInteger = require('../internals/does-not-exceed-safe-integer');
  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. // We can't use this feature detection in V8 since it causes
  16. // deoptimization and serious performance degradation
  17. // https://github.com/zloirock/core-js/issues/679
  18. var IS_CONCAT_SPREADABLE_SUPPORT = V8_VERSION >= 51 || !fails(function () {
  19. var array = [];
  20. array[IS_CONCAT_SPREADABLE] = false;
  21. return array.concat()[0] !== array;
  22. });
  23. var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
  24. var isConcatSpreadable = function (O) {
  25. if (!isObject(O)) return false;
  26. var spreadable = O[IS_CONCAT_SPREADABLE];
  27. return spreadable !== undefined ? !!spreadable : isArray(O);
  28. };
  29. var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
  30. // `Array.prototype.concat` method
  31. // https://tc39.es/ecma262/#sec-array.prototype.concat
  32. // with adding support of @@isConcatSpreadable and @@species
  33. $({ target: 'Array', proto: true, arity: 1, forced: FORCED }, {
  34. // eslint-disable-next-line no-unused-vars -- required for `.length`
  35. concat: function concat(arg) {
  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 = lengthOfArrayLike(E);
  44. doesNotExceedSafeInteger(n + len);
  45. for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
  46. } else {
  47. doesNotExceedSafeInteger(n + 1);
  48. createProperty(A, n++, E);
  49. }
  50. }
  51. A.length = n;
  52. return A;
  53. }
  54. });