array的原型上面有着很多种方法,本文将实现forEach,filter,map,some,reduce这五种方法!
原文链接:共众号:前端从进阶到入院 的 死磕36个js手写题
forEach
Array.prototype.myForEach=function(callback, thisArgs){
if(typeof this !=='array'){
throw new TypeError('this is need array!')
}
if(typeof callback !=='function'){
throw new TypeError('callback is not a function!')
}
let O=Object(this);
let len=O.length >>> 0;
let k=0;
while(k < len){
if(k in O){
callback.call(thisArgs, O[k], k, O);
}
k++;
}
}
分析一下代码:
1.this为foreach前面的数组,进行判断
2.callback为要执行的函数,进行函数
3.Object(),根据传入的值返回相应的实例
4.>>两个右箭头为有符号右移,即保存正负值。>>>三个右箭头为无符号右移,会将负数转换成正整数,小数转换成整数。0表示位移位数。证这个len是有意义的,因为length可以显示的修改
5.if(k in O)是判断数组当前位置是否有意义,如果为empty返回false
6.thisArgs为forEach的第二个函数值,不传值为undefind,此时callback在window下执行
map
Array.prototype.myForEach=function(callback, thisArgs){
if(typeof this !=='array'){
throw new TypeError('this is need array!')
}
if(typeof callback !=='function'){
throw new TypeError('callback is not a function!')
}
let O=Object(this);
let len=O.length >>> 0;
let k=0;
let res=[];
while(k < len){
if(k in O){
res[k]=callback.call(thisArgs, O[k], k, O);
}
k++;
}
return res;
}
只修改了三处代码
1.map有返回值,定于一个res;
2.将执行完函数的返回值放进数组
3.返回数组
filter
Array.prototype.myForEach=function(callback, thisArgs){
if(typeof this !=='array'){
throw new TypeError('this is need array!')
}
if(typeof callback !=='function'){
throw new TypeError('callback is not a function!')
}
let O=Object(this);
let len=O.length >>> 0;
let k=0;
let res=[];
while(k < len){
if(k in O){
if(callback.call(thisArgs, O[k], k, O)){
res[k]=O[k];
}
}
k++;
}
return res;
}
some
Array.prototype.myForEach=function(callback, thisArgs){
if(typeof this !=='array'){
throw new TypeError('this is need array!')
}
if(typeof callback !=='function'){
throw new TypeError('callback is not a function!')
}
let O=Object(this);
let len=O.length >>> 0;
let k=0;
while(k < len){
if(k in O){
if(callback.call(thisArgs, O[k], k, O)){
return true;
}
}
k++;
}
return false;
}
some就是有true,就返回true
reduce
Array.prototype.myForEach=function(callback, initValue){
if(typeof this !=='array'){
throw new TypeError('this is need array!')
}
if(typeof callback !=='function'){
throw new TypeError('callback is not a function!')
}
let O=Object(this);
let len=O.length >>> 0;
let k=0;
let acc;
if(arguments.length>0){
acc=initValue;
}else{
if( k<len && !(k in O) ){
k++;
}
if(k>len){
throw new TypeError('All is empty');
}
acc=O[k++];
}
while(k < len){
if(k in O){
acc=callback(acc, O[k], k, O);
}
k++;
}
return acc;
}
reduce的实现变化比较大
1.传入的参数不同,initValue为初始值
2.进行判断有没有传入初始值,传入取传入,不传取数组第一个有效值
3.acc=O[k++],k++会使k在接下来的代码中k=k+1,因为取了第一个数,就从第二个开始算起
4.返回最后整合的数