开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情
数组的API:forEach、map、filter、reduce、push、pop
笔者为了方便自己记忆,把这些方法大概抽离出了一个框架,这样子,写的时候,只需根据API的特性,向其中填入代码。
Array.prototype.arr = function(callback, thisArg) {
if (this === undefined) {
throw new Error('error')
}
if (typeof callback !== "function") {
throw new Error('error')
}
const O = Object(this)
const len = O.length >>> 0
for (let i = 0; i < len; i++) {
if (i in O) {
callback.call(thisArg, O[i], i, O)
}
}
}
首先,判断对一些异常情况做处理。对数组的每一个数据做一个遍历,使用传入的回调函数进行处理。
Array.prototype.forEach()
思路:对传入的数字,每一个都是用回调函数进行处理
Array.prototype.forEach = function (callback, thisArg) {
console.log('forEach')
if (this === undefined) {
throw new Error('error')
}
if (typeof callback !== "function") {
throw new Error('error')
}
const O = Object(this)
const len = O.length >>> 0
for (let i = 0; i < len; i++) {
if (i in O) {
callback.call(thisArg, O[i], i, O)
}
}
}
Array.prototype.map()
思路:
- map 会返回一个处理之后的数组,所以需要 result 数组作为返回值
- result 数组中的值,就等于回调函数返回来的值
Array.prototype.map = function (callback, thisArg) {
console.log('map')
if (this === undefined) {
throw new Error('error')
}
if (typeof callback !== "function") {
throw new Error('error')
}
const O = Object(this)
const len = O.length >>> 0
const result = []
for (let i = 0; i < len; i++) {
if (i in O) {
result[i] = callback.call(thisArg, O[i], i, O)
}
}
return result
}
Array.prototype.filter()
思路:
- filter 会返回一个处理之后的数组,所以需要 result 数组作为返回值
- 符合回调函数的,则依次加入到数组中
Array.prototype.filter = function (callback, thisArg) {
console.log('filter')
if (this === undefined) {
throw new Error('error')
}
if (typeof callback !== "function") {
throw new Error('error')
}
const O = Object(this)
const len = O.length >>> 0
const result = []
let resultLen = 0
for (let i = 0; i < len; i++) {
if (i in O) {
if (callback.call(thisArg, O[i], i, O)) {
result[resultLen++] = O[i]
}
}
}
return result
}
Array.prototype.reduce()
思路:
- reduce 会返回一个处理之后的数组,所以需要 result 变量作为返回值
- 将 callback 处理之后的函数值赋值给 result 变量
- 判断当初始值为0的时候,需要从传入的数组中获取到一个值,做为初始值
- 复用 i 变量
Array.prototype.reduce = function (callback, initValue) {
console.log('reduce')
if (this === undefined) {
throw new Error('error')
}
if (typeof callback !== "function") {
throw new Error('error')
}
const O = Object(this)
const len = O.length >>> 0
let result = initValue
let i = 0
if (initValue === undefined) {
for (; i < len; i++) {
if (i in O) {
result = O[i]
i++
break
}
}
}
for (; i < len; i++) {
if (i in O) {
result = callback.call(undefined, result, O[i], i, O)
}
}
return result
}
思路:
- push 会返回一个处理之后的数组长度,所以需要 result 变量作为返回值
- 在处理之前,需要判断长度是否超出最大值
- 遍历传入的参数,添加到原先的数组中
Array.prototype.push = function (...items) {
console.log('push')
if (this === undefined) {
throw new Error('error')
}
const O = Object(this)
const len = O.length >>> 0
const argsCount = items.length >>> 0
if (len + argsCount > 2 ** 53 - 1) {
throw new Error('error')
}
let result = len + argsCount
O.length = result
for (let i = 0; i < argsCount; i++) {
O[len + i] = items[i]
}
return result
}
Array.prototype.pop()
思路:
- pop 会返回数组中最后一个数据,所以需要 result 变量作为返回值
- 在处理之前,需要判断长度是否为 0
- 减去数组长度
- 获取数组最后一个数据,作为返回值
- 删除该数据
Array.prototype.pop = function () {
console.log('pop')
if (this === undefined) {
throw new Error('error')
}
const O = Object(this)
let len = O.length >>> 0
if (len === 0) {
O.length = 0
return undefined
}
len--
let result = O[len]
delete O[len]
O.length = len
return result
}