es.array.splice.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. 'use strict';
  2. var $ = require('../internals/export');
  3. var toAbsoluteIndex = require('../internals/to-absolute-index');
  4. var toInteger = require('../internals/to-integer');
  5. var toLength = require('../internals/to-length');
  6. var toObject = require('../internals/to-object');
  7. var arraySpeciesCreate = require('../internals/array-species-create');
  8. var createProperty = require('../internals/create-property');
  9. var arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');
  10. var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('splice');
  11. var max = Math.max;
  12. var min = Math.min;
  13. var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
  14. var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded';
  15. // `Array.prototype.splice` method
  16. // https://tc39.es/ecma262/#sec-array.prototype.splice
  17. // with adding support of @@species
  18. $({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {
  19. splice: function splice(start, deleteCount /* , ...items */) {
  20. var O = toObject(this);
  21. var len = toLength(O.length);
  22. var actualStart = toAbsoluteIndex(start, len);
  23. var argumentsLength = arguments.length;
  24. var insertCount, actualDeleteCount, A, k, from, to;
  25. if (argumentsLength === 0) {
  26. insertCount = actualDeleteCount = 0;
  27. } else if (argumentsLength === 1) {
  28. insertCount = 0;
  29. actualDeleteCount = len - actualStart;
  30. } else {
  31. insertCount = argumentsLength - 2;
  32. actualDeleteCount = min(max(toInteger(deleteCount), 0), len - actualStart);
  33. }
  34. if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER) {
  35. throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);
  36. }
  37. A = arraySpeciesCreate(O, actualDeleteCount);
  38. for (k = 0; k < actualDeleteCount; k++) {
  39. from = actualStart + k;
  40. if (from in O) createProperty(A, k, O[from]);
  41. }
  42. A.length = actualDeleteCount;
  43. if (insertCount < actualDeleteCount) {
  44. for (k = actualStart; k < len - actualDeleteCount; k++) {
  45. from = k + actualDeleteCount;
  46. to = k + insertCount;
  47. if (from in O) O[to] = O[from];
  48. else delete O[to];
  49. }
  50. for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1];
  51. } else if (insertCount > actualDeleteCount) {
  52. for (k = len - actualDeleteCount; k > actualStart; k--) {
  53. from = k + actualDeleteCount - 1;
  54. to = k + insertCount - 1;
  55. if (from in O) O[to] = O[from];
  56. else delete O[to];
  57. }
  58. }
  59. for (k = 0; k < insertCount; k++) {
  60. O[k + actualStart] = arguments[k + 2];
  61. }
  62. O.length = len - actualDeleteCount + insertCount;
  63. return A;
  64. }
  65. });