索引
空位不是 undefined,一个位置的值等于 undefined,依然是有值的。空位是没有任何值,in 运算符可以说明这一点。
0 in [undefined, undefined, undefined]; // true
0 in [, , ,]; // false
ES5 对空位的处理,已经很不一致了,大多数情况下会忽略空位。
- forEach(), filter(), reduce(), every() 和 some()都会跳过空位。
- map()会跳过空位,但会保留这个值
- join()和 toString()会将空位视为 undefined,而 undefined 和 null 会被处理成空字符串。
结论:an empty handle 是一个空的由 v8 垃圾收集器管理的对象引用,不是 undefined,所以 arr.indexOf(undefined)返回-1。
Array.prototype.reduce = function () {
const fn = arguments[0];
const array = this;
let prev = arguments.length == 2 ? arguments[1] : array[0];
let startIndex = arguments.length == 2 ? 0 : 1;
for (let i = startIndex; i < array.length; i++) {
prev = fn.call(this, prev, array[i], i, array);
}
return prev;
};
Array.prototype.reduceRight = function () {
const fn = arguments[0];
const array = this;
let prev = arguments.length == 2 ? arguments[1] : array[array.length - 1];
const startIndex =
arguments.length == 2 ? array.length - 2 : array.length - 1;
for (let i = startIndex; i >= 0; i--) {
prev = fn.call(this, prev, array[i], i, array);
}
return prev;
};
Array.prototype.map = function (fn) {
const array = this;
const result = [];
for (let i = 0; i < array.length; i++) {
result.push(fn.call(this, array[i], i, array));
}
return result;
};
Array.prototype.filter = function (fn) {
const array = this;
const result = [];
for (let i = 0; i < array.length; i++) {
const res = fn.call(this, array[i], i, array);
if (res) {
result.push(array[i]);
}
}
return result;
};
Array.prototype.every = function (fn) {
const array = this;
let flag = true;
for (let i = 0; i < array.length; i++) {
if (!fn.call(this, array[i], i, array)) {
flag = false;
}
}
return flag;
};
Array.prototype.some = function (fn) {
const array = this;
const result = [];
let flag = false;
for (let i = 0; i < array.length; i++) {
if (fn.call(this, array[i], i, array)) {
flag = true;
}
}
return flag;
};
Array.prototype.flat = function () {
const level = arguments.length == 1 ? arguments[0] : 1;
const array = this;
const result = [];
function flat(array, level, result) {
if (array instanceof Array) {
if (level <= 0) {
result.push(...array);
return;
}
} else {
result.push(array);
return;
}
for (let i = 0; i < array.length; i++) {
flat(array[i], level - 1, result);
}
}
flat(array, level, result);
return result;
};