15.4.4.12 Array.prototype.splice(start, deleteCount[, item1[, item2[, ... ]]])

2010-07-05

array Array.prototype.splice(start:int|mixed, deleteCount:int|mixed[, item1:mixed[, item2:mixed[, ... ]]])

Remove a given number of elements starting at index start moving upwards and insert item0 .. itemn at that position in that order afterwards. The removed elements are returned in an array.

The this value is coerced to an object, start to an unsigned integer and deleteCount to an integer. If start is negative, it is assumed to be len+start.

Array.prototype.splice.length = 2

Code: (Meta Ecma)
Array.prototype.splice = function(start, deleteCount){
var O = ToObject(this);
var A = new Array;
var lenVal = O.[[Get]]("length");
var len = ToUint32(lenVal);
var relativeStart = ToInteger(start);
if (relativeStart < 0) var actualStart = Math.max(len+relativeStart, 0);
else acutalStart = Math.min(relativeStart, len);
var actualDeleteCount = Math.min(Math.max(ToInteger(deleteCount), 0), len-actualStart);
var k = 0;
while (k < actualDeleteCount) {
var from = ToString(relativeStart + k);
var fromPresent = O.[[HasProperty]](from);
if (fromPresent) {
var fromValue = O.[[Get]](from);
A.[[DefineOwnProperty]](ToString(k), PD{[[Value]]:fromValue, [[Writable]]:true, [[Enumerable]]:true, [[Configurable]]:true}, false);
}
++k;
}
var items = Array.prototype.slice.call(arguments, 2);
var itemCount = items.length;
if (itemCount < actualDeleteCount) {
var k = actualStart;
while (k < (len-actualDeleteCount)) {
var from = ToString(k+actualDeleteCount);
var to = ToString(k+itemCount);
var fromPresent = O.[[HasProperty]](from);
if (fromPresent) {
var fromValue = O.[[Get]](from);
O.[[Put]](to, fromValue, true);
} else {
O.[[Delete]](to, true);
}
}
var k = len;
while (k > (len - actualDeleteCount + itemCount)) {
O.[[Delete]](ToString(k-1), true);
--k;
}
} else if (itemCount > actualDeleteCount) {
var k = len - actualDeleteCount;
while (k > actualStart) {
var from = ToString(k + actualDeleteCount - 1);
var to = ToString(k + itemCount - 1);
var fromPresent = O.[[HasProperty]](from);
if (fromPresent) {
var fromValue = O.[[Get]](from);
O.[[Put]](to, fromValue, true);
} else {
O.[[Delete]](to, true);
}
--k;
}
}
var k = actualStart;
while (items.length) {
var E = items.shift();
O.[[Put]](ToString(k), E, true);
++k;
}
O.[[Put]]("length", len - actualDeleteCount + itemCount, true);
return A;
}