本篇文章主要结合官方解释以及个人理解对 reduce()、filter()、map()、every()、some()、展开运算符 做些总结。
1、reduce()
概述:
reduce() 方法接收一个函数作为累加器( accumulator ),数组中的每个值( 从左到右 ),开始合并,最终为一个值。
语法:
array.reduce(callback, [initialValue])
参数解释如下:
- callback:执行数组中每个值的函数( 也可以叫reducer ),包含四个参数。
- previousValue:上一次调用回调返回的值,或者是提供的初始值( initailValue )。
- currentValue:数组中当前被处理的元素。
- index:当前元素在数组中的索引。
- array:调用 reduce 的数组
- initialValue:作为第一次调用callback的第一个参数。非必需。
示例一
const completedCount = todos.reduce(
( count, todo ) => ( todo.completed ? count + 1 : count ),
0
);
代码解释:
todos是一个数组。
reduce() 的第一个参数是箭头函数,这个箭头函数的第一个参数 count 是上一个的返回值( previousValue ),第二个参数todo是当前元素的值 ( currentValue )。
reduce() 的第二个参数0是个初始化值,作用是使 count 的初始值为0。
本示例目的为获取已完成条目的个数,即 completedCount,遍历数组的第一个值时,count 的值为0,todo 即当前遍历的元素,如果当前遍历的元素的 completed 为 true 的话,将 count + 1,否则返回 count 。遍历数组第二个值时,count 即遍历上一个元素时的返回值,此时 todo 为元素中的第二项,返回值加一或不变。
示例二
export default function todos(state = initialState, action) {
switch (action.type) {
case ADD_TODO:
return [
{
id: state.reduce((maxId, todo) => Math.max(todo.id, maxId), -1) + 1,
completed: false,
text: action.text,
},
...state,
];
default:
return state;
}
}
代码解释:
本示例目的为添加新的条目,即 ADD_TODO ,遍历数组的第一个值时,maxId 的值为 -1,如果此时数组中没有元素,则返回 -1 后 +1,新的条目的 index 则为0,如果有第一个值时,todo 即为当前项,todo.id 则为 0,maxId 为 -1,取最大的,返回 0 后 +1 , 新的条目的 index 为 1。遍历数组第二个值时, maxId 即遍历上一个元素时的返回值,此时 todo 元素为数组中的第二项,返回值取最大的一个。
2、filter()
概述:
filter() 方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组。
语法:
array.filter(callback [, thisArg])
参数解释如下:
- callback:用来测试数组的每个元素的函数,包含三个参数。返回 true 表示保留该元素( 通过测试 ),返回 false 则不保留。
- currentValue:数组中当前被传递的元素。
- index:元素的索引。
- array:被遍历的数组
- thisArg:执行 callback 时使用的 this 值。非必需。
示例
export default function todos(state = initialState, action) {
switch (action.type) {
case DELETE_TODO:
return state.filter(todo =>
todo.id !== action.id
);
default:
return state;
}
}
代码解释:
箭头函数的 todo 参数为当前项元素,箭头后面的判断语句,如果返回 true 则保留当前项,反之则移除当前项。本示例目的为删除一个条目,遍历数组,如果当前项的 id 与要删除条目的 id 不相等时,保留该项,否则删除该项。
3、map()
概述:
map() 方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组。
语法:
array.map(callback [, thisArg])
参数解释如下:
- callback:原数组中的元素调用该方法后返回一个新的元素。该方法包含如下三个参数。
- currentValue:数组中当前被传递的元素。
- index:元素的索引。
- array:被遍历的数组
- thisArg:执行 callback 时使用的 this 值。非必需。
示例
export default function todos(state = initialState, action) {
switch (action.type) {
case EDIT_TODO:
return state.map(todo => (
todo.id === action.id ?
Object.assign({}, todo, { text: action.text }) :
todo
));
default:
return state;
}
}
代码解释:
本示例目的为修改一个条目的内容,遍历数组,返回值为一个三元运算符,当当前项的 id 与 action.id ( 要操作的项的id ) 相同时,使用 Object.assign() 方法操作其参数,在此处的 Object.assign() 的三个参数中,第一个参数为要返回的目标对象,后面的对象都为源对象,此函数的目的是将后面的所有源对象拷贝到目标对象中,再返回目标对象。此处使用该函数的目的为,如果当前项为要修改的项,此时的 todo 就是该项,然后将其与 { text: action.text } 拷贝到 {} 中,todo 本身的 text 属性则会被 { text: action.text } 中的 action.text 所覆盖,此时就起到了修改的作用。如果当前项不是要修改的项,则原样返回 。
4、every()
概述:
every() 方法用于测试数组中所有元素是否都通过了指定函数的测试。
语法:
array.every(callback [, thisArg])
参数解释如下:
- callback:用来测试每个元素的函数。
- currentValue:数组中当前被传递的元素。
- index:元素的索引。
- array:被遍历的数组
- thisArg:执行 callback 时使用的 this 值。非必需。
示例
const areAllMarked = state.every(todo => todo.completed)
代码解释:
本示例目的为检查是否所有条目的 completed 属性均为 true,如果是的话,则返回 true,否则返回 false 。
5、some()
概述:
some() 方法用于测试数组中是否至少有一项元素通过了指定函数的测试。
语法:
array.some(callback [, thisArg])
参数解释如下:
- callback:用来测试每个元素的函数。
- currentValue:数组中当前被传递的元素。
- index:元素的索引。
- array:被遍历的数组
- thisArg:执行 callback 时使用的 this 值。非必需。
示例
const atLeastOneMarked = state.some(todo => todo.completed)
代码解释:
本示例目的为检查是否至少有一个条目的 completed 属性均为 true,如果是的话,则返回 true,否则返回 false 。
6、展开运算符
概述:
展开运算符允许一个表达式在某处展开。常用的场景包括:函数参数、数组元素、解构赋值。另外,JSX中的组件 props 也可以使用展开运算符来赋值。
语法:
// 用于函数参数:
myFunction(...iterableObj);
// 用于数组元素:
[...iterableObj, 4, 5, 6];
// 用于解构赋值:
const [ a, b, ...rest ] = [ 1, 2, 3, 4, 5 ];
const { a, b, ...rest } = { a: 1, b: 2, c: 3, d: 4 };
// 用于 React 组件的 props:
示例一
return [
{
id: state.reduce((maxId, todo) => Math.max(todo.id, maxId), -1) + 1,
completed: false,
text: action.text,
},
...state,
];
代码解释:
展开 state 数组的每一项到当前的数组。
示例二
展开 actions 中的每一个属性到组件中。