| 'use strict'; |
| var $ = require('../internals/export'); |
| var toAbsoluteIndex = require('../internals/to-absolute-index'); |
| var toInteger = require('../internals/to-integer'); |
| var toLength = require('../internals/to-length'); |
| var toObject = require('../internals/to-object'); |
| var arraySpeciesCreate = require('../internals/array-species-create'); |
| var createProperty = require('../internals/create-property'); |
| var arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support'); |
| |
| var max = Math.max; |
| var min = Math.min; |
| var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; |
| var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded'; |
| |
| // `Array.prototype.splice` method |
| // https://tc39.github.io/ecma262/#sec-array.prototype.splice |
| // with adding support of @@species |
| $({ target: 'Array', proto: true, forced: !arrayMethodHasSpeciesSupport('splice') }, { |
| splice: function splice(start, deleteCount /* , ...items */) { |
| var O = toObject(this); |
| var len = toLength(O.length); |
| var actualStart = toAbsoluteIndex(start, len); |
| var argumentsLength = arguments.length; |
| var insertCount, actualDeleteCount, A, k, from, to; |
| if (argumentsLength === 0) { |
| insertCount = actualDeleteCount = 0; |
| } else if (argumentsLength === 1) { |
| insertCount = 0; |
| actualDeleteCount = len - actualStart; |
| } else { |
| insertCount = argumentsLength - 2; |
| actualDeleteCount = min(max(toInteger(deleteCount), 0), len - actualStart); |
| } |
| if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER) { |
| throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED); |
| } |
| A = arraySpeciesCreate(O, actualDeleteCount); |
| for (k = 0; k < actualDeleteCount; k++) { |
| from = actualStart + k; |
| if (from in O) createProperty(A, k, O[from]); |
| } |
| A.length = actualDeleteCount; |
| if (insertCount < actualDeleteCount) { |
| for (k = actualStart; k < len - actualDeleteCount; k++) { |
| from = k + actualDeleteCount; |
| to = k + insertCount; |
| if (from in O) O[to] = O[from]; |
| else delete O[to]; |
| } |
| for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1]; |
| } else if (insertCount > actualDeleteCount) { |
| for (k = len - actualDeleteCount; k > actualStart; k--) { |
| from = k + actualDeleteCount - 1; |
| to = k + insertCount - 1; |
| if (from in O) O[to] = O[from]; |
| else delete O[to]; |
| } |
| } |
| for (k = 0; k < insertCount; k++) { |
| O[k + actualStart] = arguments[k + 2]; |
| } |
| O.length = len - actualDeleteCount + insertCount; |
| return A; |
| } |
| }); |