开始
上一节,对数组的5个API 进行了总结整理,下面接着根据MDN 上的顺序整理。
数组方法
Array.prototype.every()
作用
every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值,数组为空返回true。
应用
console.log([].every(a=>a>1));//true
console.log([1,2,4].every(a=>a>1)) //false
console.log([1,2,4].every(a=>a>0)) //true
console.log([1,2,4]._every(function (a){ return a>this.n},{n:0}));//true
以前只知道传callback 参数,但是还有一个传参 thisArg,表示的是执行callback的this值,加上了thisArg参数,callback就不要用箭头函数了,因为箭头函数的this无法改变。
实现
思路
- 在数组原型上定义方法。
- 数组为空永远返回true。
- 传入了thisArg 参数要更改回调函数的this指向。
代码实现
Array.prototype._every=function (callback,thisArg) {
if(typeof callback!='function')
{
throw new TypeError('callback is not a function')
}
let target=this,res=true;
let context=thisArg ||this;
for(let i=0;i<target.length;i++)
{
//有一项不满足就返回false
if(!callback.call(context,target[i],i,target))
{
return false;
}
}
return res;
}
测试
测试得到和原生相同的结果
console.log([]._every(a=>a>1));//true
console.log([1,2,4]._every(a=>a>1)) //false
console.log([1,2,4]._every(a=>a>0)) //true
console.log([1,2,4]._every(function (a){ return a>this.n},{n:0}));//true
Array.prototype.filter()
作用
filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。也就是数组内容过滤。
应用
var a=[1,2,3,5];
console.log(a.filter((item)=>item>2));//[3,5]
console.log(a.filter((item)=>item>this.n,{n:2})); //[]
console.log(a.filter(function(item){
return item>this.n;
},{n:2}));// [3,5]
实现
下面就来具体实现该方法,其实很简单,就是对数组内容进行过滤,符合条件的加入新数组。
思路
- 在数组原型上定义方法。
- 产生一个新数组,不能影响原数组的值。
- 传入了thisArg 参数要更改回调函数的this指向。
代码实现
Array.prototype._filter=function (callback,thisArg) {
if(typeof callback!='function')
{
throw new TypeError('callback is not a function')
}
//得到上下文
let context=thisArg ||this;
//返回新数组
let target=this,res=[];
for(let i=0;i<target.length;i++)
{
//符合条件的
if(callback.call(context,target[i],i,target))
{
res.push(target[i])
}
}
return res;
}
测试
总体来说很简单,就是要记住还有 thisArg 这个参数
var a=[1,2,3,5];
console.log(a._filter((item)=>item>2)); // [3,5]
console.log(a._filter((item)=>item>this.n,{n:2})); //[]
console.log(a._filter(function(item){
return item>this.n;
},{n:2})) //[3,5]
Array.prototype.find()
作用
find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
注意只是返回的第一个值,其中还有一个Array.prototype.findIndex(),lian是返回的是第一个符合条件的索引,这个方法就不做介绍了。
实现
思路
- 在数组原型上定义该方法。
- 两个参数,callback 和 thisArg(回调函数的this指向)。
- 不要改变原数组。
- 没有结果返回 undefined
代码实现
Array.prototype._find=function (callback,thisArg) {
if(typeof callback!='function')
{
throw new TypeError('callback is not a function')
}
//上下文
let context=thisArg || this;
let target=this;
for(let i=0;i<target.length;i++)
{
//有一项不满足就返回false
if(callback.call(context,target[i],i,target))
{
return target[i];
}
}
return undefined;
}
测试
很简单的一个API,不做太多解释了,findIndex 方法和它差不多,只是返回的是索引,没有符合条件的返回的是-1。
const found = array1._find(element => element > 1000);
console.log(found);
const found2=array1._find(function(element){
return element>this.m;
},{m:100})
console.log(found2);
Array.prototype.flat()
作用
flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。也就是实现数组的扁平化
这是个开发中很重要的一个API,也是相对实现难度较高的。
实例应用
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]].flat()); //[ 1, 2, 1, [ 3, [ 4 ] ], 2, [ 3, [ 4 ] ] ]
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]].flat(2)); //[ 1, 2, 1, 3, [ 4 ], 2, 3, [ 4 ] ]
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]].flat(Infinity)); //[ 1, 2, 1, 3, 4, 2, 3, 4 ]
实现
思路
- 在数组原型上定义该方法。
- 参数deep 代表扁平化的深度,有深度就会用递归。
- 默认扁平化深度为1。
- 使用 Infinity全部扁平化
- 不会改变原数组
Array.prototype._flat=function (deep) {
//不传,不是大于1的数字都默认为1
if(!deep ||typeof deep!='number'|| deep<1)
{
deep=1;
}
deep=Math.round(deep-0);
let target=this,res=[];
_toFlat(target,0,res);
return res;
function _toFlat(arr,n=0,res=[],state=false) {
if(n>deep)
{
res.push(arr)
return;
}
for(let i=0;i<arr.length;i++)
{
//是否是再次递归的标记,等到下一项,将 n置为0
if(!state)
{
n=0;
}
if(arr[i] instanceof Array)
{
n++;
//递归,传递递归标记为true
_toFlat(arr[i],n,res,true)
}
else{
res.push(arr[i]);
}
}
}
}
测试
三种情况
- 测试默认深度为1
- 测试根据深度扁平化
- 使用Infinity代表全部扁平化
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]]._flat()); //[ 1, 2, 1, [ 3, [ 4 ] ], 2, [ 3, [ 4 ] ] ]
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]]._flat(2)); //[ 1, 2, 1, 3, [ 4 ], 2, 3, [ 4 ] ]
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]]._flat(Infinity)); //[ 1, 2, 1, 3, 4, 2, 3, 4 ]
数组原型上还有一个flatMap 方法,感觉毫无意义,不做介绍了。
Array.prototype.forEach()
forEach() 方法对数组的每个元素执行一次给定的函数。
这个方法也很常用,但是很简单,其实一个for循环就搞定了。
代码实现
Array.prototype._forEach=function(callback,thisArg){
if(typeof callback!='function')
{
throw new TypeError('callback is not a function')
}
let context=thisArg ||this;
for(let i=0;i<this.length;i++)
{
callback.call(context,this[i],i,this)
}
}
测试
很简单的一个方法,简单测试一下即可
const array1 = ['a', 'b', 'c'];
array1._forEach(element => console.log(element));
//依次打印 a,b,c
网友评论