Array.prototype.map
Array.prototype.map2 = function(callbackfn, thisArg) {
if (this == null) {
throw new TypeError('Cannot read property "map" of null or undefined')
}
// 因为类数组对象也可以调用map方法,[].map.call(arguments,...)
// 所以需要转出数组
let O = Object(this)
// 这行确保len是非负数,并且可以把非数字转换成0
let len = O.length >>> 0
if (typeof callbackfn !== 'function') {
throw new TypeError(callbackfn+'is not a function')
}
let T = thisArg
let A = new Array(len)
let k = 0
while (k < len) {
if (k in O) {
let mappedValue = callbackfn.call(T,O[k],k,O)
A[k] = mappedValue
}
k ++
}
return A
}
let arrMap = [1,2,3]
console.log(arrMap.map2(item => item + 1))
Array.prototype.filter
Array.prototype.filter2 = function(callbackfn, thisArg) {
if (this == null) {
throw new TypeError('Cannot read property "map" of null or undefined')
}
// 因为类数组对象也可以调用filter方法,[].filter.call(arguments,...)
// 所以需要转出数组
let O = Object(this)
// 这行确保len是非负数,并且可以把非数字转换成0
let len = O.length >>> 0
if (typeof callbackfn !== 'function') {
throw new TypeError(callbackfn+'is not a function')
}
let T = thisArg
let A = new Array(len)
let k = 0
let to = 0
while (k < len) {
if (k in O) {
if (callbackfn.call(T,O[k],k,O)) {
A[to++] = O[k]
}
}
k ++
}
A.length = to
return A
}
let arrFilter = [1,2,3]
console.log(arrFilter.filter2(item => item >= 2))
Array.prototype.reduce
Array.prototype.reduce2 = function(callbackfn, initValue) {
if (this == null) {
throw new TypeError("Cannot read property 'reduce' of null or undefined");
}
if (typeof callbackfn !== 'function') {
throw new TypeError(callbackfn + ' is not a function')
}
let O = Object(this), accu = 0, len = O.length >>> 0, k = 0
if (initValue) {
accu = initValue
} else {
if (len == 0) {
throw new TypeError('Reduce of empty array with no initial value');
}
let kFlag = false
while (!kFlag && (k < len)) {
if (k in O) {
kFlag = true
accu = O[k]
}
k ++
}
}
while (k < len) {
if (k in O) {
accu = callbackfn.call(undefined,accu, O[k],k,O)
}
k ++
}
return accu
}
arr = [1,2,3]
console.log(arr.reduce2((p,c) => { return p + c }))
Array.prototype.flat
// reduce + concat + 递归
function flat2(arr, d = 1) {
return d > 0 ? arr.reduce((pre,curr) => pre.concat(Array.isArray(curr) ? flat2(curr,d-1) : curr), []) : arr.slice()
}
// 使用堆栈实现
function flat3(arr) {
let stack = [...arr], res = []
while(stack.length) {
const next = stack.pop()
if (Array.isArray(next)) {
stack.push(...next)
} else {
res.push(next)
}
}
return res.reverse()
}
Array.prototype.flat2 = function(d = 1) {
return flat2(this,d)
}
Array.prototype.flat3 = function() {
return flat3(this)
}
var arr1 = [1,2,3,[1,2,3,4, [2,3,4,[5]]]];
console.log(arr1.flat2(Infinity))
console.log(arr1.flat3())