这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
JS中有很多实用的内置方法,尝试自己去实现相同功能的方法有助于我们加强我们对这些方法的理解,以达到更好的使用这些方法的目的,同时手写方法也是面试中常常考察的点。
map
语法:
var new_array = arr.map(function callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg])
thisArg执行 callback 函数时值被用作this。
Array.prototype.fakeMap = function(fn,context ) {
let result = []
for(let i = 0;i<this.length;i++){
if(!this.hasOwnProperty(i)) continue; // 处理稀疏数组的情况
result.push(fn.call(context,this[i],i,this))
}
return result
}
var arr = [1,2,3]
var arrSum = arr.fakeMap(item => item+2)
console.log(arrSum)
// 验证this,使用箭头函数,this指向windows对象
var obj1 = {a:3}
var arr1 = [1,2,3]
var arrSum1 = arr1.fakeMap((item) => {
console.log(this.a)
return this.a+item
},obj1)
console.log(arrSum1)
// 验证 this,this指向obj3
var arr3 = ["x", "y", "z"];
var obj3 = { a: 1 };
var result3 = arr3.fakeMap(function(item) {
console.log(this.a);
return item + this.a
}, obj3);
console.log(result3)
filter
语法
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
Array.prototype.fakeFilter = function(fn,context){
let result = []
for(let i=0; i<this.length; i++){
if(!this.hasOwnProperty(i)) continue;
if(fn.call(context,this[i],i,this)){
result.push(this[i])
}
}
return result
}
var arr = [1,2,3]
var obj = {a:2}
console.log(arr.fakeFilter(item => item>1))
// 验证this
console.log(arr.fakeFilter(function(item){
return item>this.a
},obj))
reduce
语法
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
Array.prototype.fakeReduce = function(fn,initialValue){
//let result = initialValue||this[0]
// 处理初始值为0的情况
let result = typeof(initialValue)==='undefined'?this[0]:initialValue
console.log(initialValue,result)
for(let i= typeof(initialValue)!=='undefined'?0:1;i<this.length;i++){
if(!this.hasOwnProperty(i)) continue; // 处理稀疏数组的情况
let currentValue = this[i]
console.log("currentValue",currentValue)
result = fn(result,currentValue,i,this)
console.log("result",result)
}
return result
}
var arr = [1,2,3]
var result = arr.fakeReduce(function(x,y){
return x+y
})
console.log(result) // 6
// 验证初始值
var result1 = arr.fakeReduce(function(x,y){
return x+y
},10)
console.log(result1) // 16
应用
累加对象中的值,必须提供初始值。
var initalValue = 0
var sum = [{x: 1}, {x:2}, {x:3}].fakeReduce(function (accumulator, currentValue) {
return accumulator + currentValue.x;
},initalValue)
console.log(sum)
every
every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值
语法
arr.every(callback(element[, index[, array]])[, thisArg])
Array.prototype.fakeEvery = function(fn,context){
let flag = true;
for(let i=0;i<this.length;i++){
if(!this.hasOwnProperty(i)) continue; // 处理稀疏数组的情况
flag = flag&&fn.call(context,this[i],i,this)
if(!flag) break
}
return flag
}
var arr = []
var flag = arr.fakeEvery(function(item){
return item<3
})
console.log(flag)
// 验证this
var arr1 = [1,2,3]
var obj = {a:3}
var flag1 = arr1.fakeEvery(function(item){
return item<this.a
},obj)
console.log(flag1)
some
some() 方法测试一个数组内是否至少有一个元素满足回调函数的测试。返回一个布尔值。
语法
arr.some(callback(element[, index[, array]])[, thisArg])
Array.prototype.fakeSome = function(fn,context){
let flag = false;
for(let i=0;i<this.length;i++){
if(!this.hasOwnProperty(i)) continue; // 处理稀疏数组的情况
flag = fn.call(context,this[i],i,this)
if(flag) break
}
return flag
}
var arr = [1,3,4]
var flag = arr.fakeSome(function(item){
return item<3
})
console.log(flag)
// 验证this
var arr1 = [1,2,3]
var obj = {a:3}
var flag1 = arr1.fakeSome(function(item){
return item<this.a
},obj)
console.log(flag1)
find
find()方法返回数组中第一个通过测试函数的值,没有返回undefined
语法:
arr.find(callback[, thisArg])
callback:
element
index
array
Array.prototype.fakeFind = function(fn,context){
let result = undefined
for(let i=0;i<this.length;i++){
if(!this.hasOwnProperty(i)) continue; // 处理稀疏数组的情况
if(fn.call(context,this[i],i,this)){
result = this[i]
break
}
}
return result
}
//测试
;(function() {
let arr = [1,2,3]
let obj = {a:3}
let result = arr.fakeFind((item) => item>1)
let result2 = arr.fakeFind((item) =>{
console.log(this) // ? 这个this没传过来
return item>this.a
},obj)
console.log(result,result2)
})();
flat
数组扁平化
reduce
const flatten = function(arr){
if(!Array.isArray(arr)) return;
let result = []
result = arr.reduce((res,curr) => res.concat(Array.isArray(curr)?flatten(curr):curr),[])
return result
}
;(function(){
let arr = [1,2,[3,4]]
console.log(flatten(arr))
})()
堆栈
const flatten = function(arr){
if(!Array.isArray(arr)) return;
let stack = [...arr]
let result = []
while(stack.length){
let value = stack.shift()
if(Array.isArray(value)){
stack.push(...value)
}else{
result.push(value)
}
}
return result
}
let arr = [1,2,[3,4,[5,6]]]
console.log(flatten(arr))