前言
这几个方法都是js5里面最常用,性价比最高的方法,熟练使用的话可以精简掉很多代码,提高代码可读性,还可以链式调用.废话不多说,让我们开始吧!
文章目录
forEach
forEach实例
let arr=[
{user:'zs',age:20},
{user:'ls',age:30},
{user:'ww',age:40},
{user:'zl',age:50},
];
function fn(){
return arr.forEach((item,idx,arr)=>{
console.log(item,idx);
if(idx==2){return ;}
item.age+=idx;
});
}
let res=fn();
console.log(arr);
console.log(`forEach返回值${res}`);
结果:
//console.log(item,idx)
{ user: 'zs', age: 20 } 0
{ user: 'ls', age: 30 } 1
{ user: 'ww', age: 40 } 2
{ user: 'zl', age: 50 } 3
//console.log(arr)
[ { user: 'zs', age: 20 },
{ user: 'ls', age: 31 },
{ user: 'ww', age: 42 },
{ user: 'zl', age: 53 } ]
//console.log(`forEach返回值${res}`)
forEach返回值undefined
forEach讲解
- 1.由实例可知forEach参数为回调函数callback, callback有三个参数,分别是
item 每一项
,idx 每一项的索引下标
,arr 调用forEach的原数组
- 2.如果
item
是基本类型, 无法改变原数组; 如果是引用类型,则会改变原数组 - 3.在callback函数中调用return, 只会结束当前item项的函数, 不会跳出forEach, 更不会跳出fn函数; 所以如果有判断条件跳出fn函数的需求, 应该使用
for-in
循环 - 4.callback中不需要写
return xxx;
因为forEach是直接修改原数组, 所以callback中返回没有意义, 注意return 后面的代码不会执行 - 5.
forEach
方法没有返回值 - 6.注意实例中用的是es6的箭头函数, 所以回调中的this是fn函数的当前上下文; 如果改为es5的
function(){}
,则回调函数中的this是window|global
,并不是arr - 7.
总结
:forEach方法遍历数组, callback直接修改原数组,callback中可以不返回
forEach浏览器源码实现
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
var O = Object(this);
var len = O.length >>> 0;
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function');
}
if (arguments.length > 1) {
T = thisArg;
}
k = 0;
while (k < len) {
var kValue;
if (k in O) {
kValue = O[k];
callback.call(T, kValue, k, O);
}
k++;
}
};
}
map
map实例
let arr=[
{user:'zs',age:20},
{user:'ls',age:30},
{user:'ww',age:40},
{user:'zl',age:50},
];
function fn(){
return arr.map((item,idx,arr)=>{
console.log(item,idx);
if(idx==2){return;}
return item;
});
}
let res=fn();
console.log(arr);
console.log(res);
结果:
//console.log(item,idx)
{ user: 'zs', age: 20 } 0
{ user: 'ls', age: 30 } 1
{ user: 'ww', age: 40 } 2
{ user: 'zl', age: 50 } 3
//console.log(arr)
[ { user: 'zs', age: 20 },
{ user: 'ls', age: 30 },
{ user: 'ww', age: 40 },
{ user: 'zl', age: 50 } ]
//console.log(res)
[ { user: 'zs', age: 20 },
{ user: 'ls', age: 31 },
undefined,
{ user: 'zl', age: 53 } ]
map讲解
- 1.由实例可知map参数为回调函数callback, callback有三个参数,分别是
item 每一项
,idx 每一项的索引下标
,arr 调用map的原数组
- 2.无论在callback中怎么操作,都不会修改原数组; 只会将结果返回到新数组中,
更正:如果回调的item是引用类型,修改item会修改原数组
- 3.在callback函数最后必须调用return item, 否则map返回的数组中对应项为undefined
- 4.注意实例中用的是es6的箭头函数, 所以回调中的this是fn函数的当前上下文; 如果改为es5的
function(){}
,则回调函数中的this是window|global
,并不是arr - 5.
总结
:map方法遍历数组, callback直接不修改原数组,返回新数组,callback最后必须return item
map浏览器源码实现
if (!Array.prototype.map) {
Array.prototype.map = function(callback, thisArg) {
var T, A, k;
if (this == null) {
throw new TypeError(" this is null or not defined");
}
var O = Object(this);
var len = O.length >>> 0;
if (Object.prototype.toString.call(callback) != "[object Function]") {
throw new TypeError(callback + " is not a function");
}
if (thisArg) {
T = thisArg;
}
A = new Array(len);
k = 0;
while(k < len) {
var kValue, mappedValue;
//遍历O,k为原数组索引
if (k in O) {
//kValue为索引k对应的值.
kValue = O[ k ];
// 执行callback,this指向T,参数有三个.分别是kValue:值,k:索引,O:原数组.
mappedValue = callback.call(T, kValue, k, O);
// 返回值添加到新数组A中.
A[ k ] = mappedValue;
}
k++;
}
return A;
};
}
every
every实例
let arr=[5,6,7,8,9];
let res1=arr.every((item,idx,arr)=>{
return item>4;
});
let res2=arr.every((item,idx,arr)=>{
return item>7;
});
console.log(arr);
console.log(res1);
console.log(res2);
结果
//console.log(arr);
[ 5, 6, 7, 8, 9 ]
//console.log(res1);
true
//console.log(res2);
false
every讲解
- 1.every方法表示遍历数组,判断是否每一项都符合条件,如果是则返回
true
, 只要存在不符合条件的项则返回false
- 2.由实例可知every参数为回调函数callback, callback有三个参数,分别是
item 每一项
,idx 每一项的索引下标
,arr 调用every的原数组
- 3.无论在callback中怎么操作,都不会修改原数组; 只会返回Boolean类型值
- 4.在callback函数最后必须调用
return condition
, 否则every返回false
- 5.注意实例中用的是es6的箭头函数, 所以回调中的this是fn函数的当前上下文; 如果改为es5的
function(){}
,则回调函数中的this是window|global
,并不是arr
every浏览器源码实现
if (!Array.prototype.every)
{
Array.prototype.every = function(fun /*, thisArg */)
{
'use strict';
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function')
throw new TypeError();
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++)
{
if (i in t && !fun.call(thisArg, t[i], i, t))
return false;
}
return true;
};
}
some
some实例
let arr=[5,6,7,8,9];
let res1=arr.some((item,idx,arr)=>{
return item>10;
});
let res2=arr.some((item,idx,arr)=>{
return item>7;
});
console.log(arr);
console.log(res1);
console.log(res2);
结果
//console.log(arr);
[ 5, 6, 7, 8, 9 ]
//console.log(res1);
false
//console.log(res2);
false
some讲解
- 1.some方法表示遍历数组,判断是否有符合条件的项,如果有则返回
true
, 如果没有一项符合条件的项则返回false
- 2.由实例可知some参数为回调函数callback, callback有三个参数,分别是
item 每一项
,idx 每一项的索引下标
,arr 调用some的原数组
- 3.无论在callback中怎么操作,都不会修改原数组; 只会返回Boolean类型值
- 4.在callback函数最后必须调用
return condition
, 否则some返回false
- 5.注意实例中用的是es6的箭头函数, 所以回调中的this是fn函数的当前上下文; 如果改为es5的
function(){}
,则回调函数中的this是window|global
,并不是arr
some浏览器源码实现
if (!Array.prototype.some)
{
Array.prototype.some = function(fun /*, thisArg */)
{
'use strict';
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function')
throw new TypeError();
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++)
{
if (i in t && fun.call(thisArg, t[i], i, t))
return true;
}
return false;
};
}
filter
filter实例
let arr=[5,6,7,8,9];
let res1=arr.filter((item,idx,arr)=>{
return item%2===0;
});
let res2=arr.filter((item,idx,arr)=>{
return item>7;
});
console.log(arr);
console.log(res1);
console.log(res2);
结果
//console.log(arr);
[ 5, 6, 7, 8, 9 ]
//console.log(res1);
[ 6, 8 ]
//console.log(res2);
[ 8, 9 ]
filter讲解
- 1.filter方法表示遍历数组,过滤出符合条件的项,如果有则返回 所有符合条件项组成的数组, 如果没有符合条件的项则返回空数组
- 2.由实例可知filter参数为回调函数callback, callback有三个参数,分别是
item 每一项
,idx 每一项的索引下标
,arr 调用filter的原数组
- 3.无论在callback中怎么操作,都不会修改原数组; 只会返回新数组
- 4.在callback函数最后必须调用
return condition
, 否则filter返回空数组 - 5.注意实例中用的是es6的箭头函数, 所以回调中的this是fn函数的当前上下文; 如果改为es5的
function(){}
,则回调函数中的this是window|global
,并不是arr
filter浏览器源码实现
if (!Array.prototype.filter)
{
Array.prototype.filter = function(fun /* , thisArg*/)
{
"use strict";
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== "function")
throw new TypeError();
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++)
{
if (i in t)
{
var val = t[i];
if (fun.call(thisArg, val, i, t))
res.push(val);
}
}
return res;
};
}
reduce和reduceRight
reduce和reduceRight实例
let arr=[1,2,3,4,5];
let res1=arr.reduce((prev,item,idx,arr)=>{
return prev+item;
},2);
let res2=arr.reduceRight((prev,item,idx,arr)=>{
return prev+item;
});
console.log(arr);
console.log(res1);
console.log(res2);
结果
//console.log(arr);
[ 1, 2, 3, 4, 5 ]
//console.log(res1);
27
//console.log(res2);
25
reduce和reduceRight讲解
- 1.reduce和reduceRight都是累加器方法,表示按callback规则累计,可以传入第二个参数作为初始值,返回累加结果
- 2.由实例可知这两个方法参数为回调函数callback和初始值prev, callback有四个参数,分别是
prev上一次遍历的结果或初始值
,item 每一项
,idx 每一项的索引下标
,arr调用的原数组
- 3.无论在callback中怎么操作,都不会修改原数组; 只会返回累加值
- 4.在callback函数最后必须调用
return expression
, 否则返回undefined - 5.reduce方法表示从最小下标项到最大累加, reduceRight表示从最大下标项到最小累加
- 6.注意实例中用的是es6的箭头函数, 所以回调中的this是fn函数的当前上下文; 如果改为es5的
function(){}
,则回调函数中的this是window|global
,并不是arr
reduce和reduceRight浏览器源码实现
//reduce
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(callback /*, initialValue*/) {
if (this == null) {
throw new TypeError('Array.prototype.reduce called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
var t = Object(this), len = t.length >>> 0, k = 0, value;
if (arguments.length == 2) {
value = arguments[1];
} else {
while (k < len && !(k in t)) {
k++;
}
if (k >= len) {
throw new TypeError('Reduce of empty array with no initial value');
}
value = t[k++];
}
for (; k < len; k++) {
if (k in t) {
value = callback(value, t[k], k, t);
}
}
return value;
};
}
//reduceRight
if ('function' !== typeof Array.prototype.reduceRight) {
Array.prototype.reduceRight = function(callback /*, initialValue*/) {
'use strict';
if (null === this || 'undefined' === typeof this) {
throw new TypeError('Array.prototype.reduceRight called on null or undefined');
}
if ('function' !== typeof callback) {
throw new TypeError(callback + ' is not a function');
}
var t = Object(this), len = t.length >>> 0, k = len - 1, value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k >= 0 && !(k in t)) {
k--;
}
if (k < 0) {
throw new TypeError('ReduceRight of empty array with no initial value');
}
value = t[k--];
}
for (; k >= 0; k--) {
if (k in t) {
value = callback(value, t[k], k, t);
}
}
return value;
};
}
(写的不对的欢迎指正, 有问题可以留言探讨!)