Хотел как лучше, а получилось сложно. Улучшаю splice.
Изначальной задачей было сделать так, чтобы функция splice могла принимать отрицательный второй аргумент и удалять значения в обратном направлении.
Допустим есть массив: var arr = [0,1,2,3,4,5]; splice(3,1); >[0,1,2,4,5] splice(3,-1); >[0,1,3,4,5] Но потом всё пошло не так. По стандарту, первые 2 аргумента обязательны, но по факту движки допускают вызов только с первым аргументом, удаляя остаток массива. Дальше приключения продолжаются! Отсутствием второго аргумента считается только вызов функции с 1 аргументом splice(0), если же вызвать метод как splice(0,undefined), то второй аргумент будет принят за ноль! Более того, нулями становятся null и даже NaN! В общем-то так ведут себя и другие методы. Решил я сделать всё аргументы не обязательными, но вот как быть с NaN пока не знаю. Пока сделал что он тоже инициирует значения по умолчанию. Потратил много времени и задача-то в общем не первой важности, стандартный splice тоже прекрасно справляется. Но сдаваться не хотелось и я всё же добил его! Назовём его пока что mySplice: mySplice(array[, start, deleteCount, item1[, item2[, ...]]]) Все аргументы, кроме массива опциональны! Это будет работать как array.push(1, 2, 3); mySplice(array, null, null, 1, 2, 3); Удаление двух элементов с начала: mySplice(array, null, 2); or mySplice(array, 0, 2); // Like original Удаление двух элементов с конца: mySplice(array, null, -2); or mySplice(array, -2, 2); // Like original or mySplice(array, Infinity, -2); Оставление двух элементов в начале: mySplice(array, 2); // Like original or mySplice(array, 2, null); // Not like original or mySplice(array, 2, Infinity); // Like original Оставление двух элементов в конце: mySplice(array, -2); or mySplice(array, -2, null); or mySplice(array, 0, array.length - 2); // Like original Но отрицательные числа приводят к другому эффекту, который, при желании, можно исправить, новые элементы будут добавляться с другой стороны. Добавит элементы перед оставшимися: mySplice(array, -2, null, 1, 2, 3); Добавит элементы после оставшихся: mySplice(array, 0, array.length - 2, 1, 2, 3); И другие возможности, которые можно понять по коду (который, к сожалению, получился не простым) или, если будет спрос, я опишу позже. isNumeric() и trunc() интегрированы, чтоб не создавать зависимостей. Жду советов по доработке. Вот сама функция:
function mySplice (arr, start, deleteCount) {
if (!Array.isArray(arr)) {
throw new Error('Argument is not an Array.');
}
var len = arr.length;
// isNumeric. Non numeric triggers default
if (!isNaN(parseFloat(start))) {
// Truncate
start = (start - start % 1) || (!isFinite(start) || start === 0 ? start : start < 0 ? -0 : 0);
} else {
start = null;
}
// isNumeric. Non numeric triggers default
if (!isNaN(parseFloat(deleteCount))) {
// Truncate
deleteCount = (deleteCount - deleteCount % 1) || (!isFinite(deleteCount) || deleteCount === 0 ? deleteCount : deleteCount < 0 ? -0 : 0);
} else {
deleteCount = null;
}
var s = start;
var dc = deleteCount;
if (start == null) {
if (deleteCount == null) {
s = len;
} else if (-len < deleteCount && deleteCount < 0) {
s = len + deleteCount;
dc = -deleteCount;
} else if (len <= deleteCount || deleteCount <= -len) { // 2
dc = len;
}
} else if (len <= start) {
if (deleteCount == null) {
dc = 0;
} else if (deleteCount <= -len) {
s = 0;
dc = len;
} else if (-len < deleteCount && deleteCount < 0) {
s = len + deleteCount;
dc = -deleteCount;
}
} else if (0 < start && start < len) {
if (deleteCount == null) {
dc = len - start;
} else if (-start < deleteCount && deleteCount < 0) {
s = start + deleteCount;
dc = -deleteCount;
} else if (deleteCount <= -start) {
dc = start;
s = 0;
}
} else if (start <= 0) {
if (deleteCount == null || len <= deleteCount) {
dc = len;
}
if (-len < start && start < 0) {
if (deleteCount == null || deleteCount <= -(len + start)) {
s = 0;
dc = len + start;
} else if (-(len + start) < deleteCount && deleteCount < 0) {
s = start + len + deleteCount;
dc = -deleteCount;
}
} else if (start <= -len) {
if (deleteCount == null) {
dc = 0;
}
}
}
// Arguments object may be not connected to locals
arguments[1] = s;
arguments[2] = dc;
var aProto = Array.prototype;
return aProto.splice.apply(arr, aProto.slice.call(arguments, 1))
}
|
| Часовой пояс GMT +3, время: 09:30. |