答案
Array.prototype.myarray = function (cb) {
return this.reduce((total, cur) => cb(cur) ? total.push(cur) && total : total, []);
};
逐行解释
-
Array.prototype.myarray = function (cb) { ... }
- 作用:给所有数组添加一个新方法
myarray
,这个方法接受一个回调函数cb
作为参数。 - 类比:就像给你的笔盒加一个“筛选笔”的功能,这个功能需要你告诉它“怎么筛选”(比如“只选红色的笔”)。
- 作用:给所有数组添加一个新方法
-
return this.reduce(...)
- 作用:用
reduce
方法遍历数组,逐步构建结果数组。 - 类比:就像用筛子过滤沙子,把符合要求的沙粒收集到新碗里。
- 作用:用
-
reduce((total, cur) => ..., [])
- 参数:
total
:最终要返回的“新碗”(初始为空数组[]
)。cur
:当前正在检查的“沙粒”(数组中的当前元素)。
- 过程:
- 每次循环,检查当前元素
cur
是否符合回调函数cb
的条件。 - 如果符合,就把
cur
放进total
(新碗)里;否则,跳过。 - 最后返回装满符合元素的
total
。
- 每次循环,检查当前元素
- 参数:
-
cb(cur) ? total.push(cur) && total : total
- 条件判断:
- 如果
cb(cur)
返回true
(符合筛选条件),则执行total.push(cur)
,把当前元素加到total
中。 - 如果返回
false
,则不操作total
,直接返回当前的total
。
- 如果
- 细节:
total.push(cur)
会把元素加到total
末尾,但push
返回的是新数组的 长度(比如加完后长度是 3)。total.push(cur) && total
是一个巧妙的写法:- 先执行
push
(确保元素被加入), - 然后返回
total
(让reduce
继续用更新后的total
进行下一轮循环)
- 先执行
- 条件判断:
疑问:
为什么需要 && total
?
问题:直接返回 total.push(cur)
会怎样?
-
push
的返回值是 数组的长度(如3
),而total
是 数组。 -
如果直接写成
total.push(cur)
,那么reduce
的返回值会是 数字(如3
),而不是数组!-
这会导致后续的
reduce
迭代中,total
变成数字,引发错误(比如数字.push()
是无效的)。
-
简单比喻
想象你有一个购物车 total
,现在要往里面放一个苹果 cur
:
total.push(cur)
:把苹果放进购物车,返回购物车的 物品数量(比如 3 个)。
&& total
:不管数量是多少(只要不是 0),最终返回的是 购物车本身(里面已经装了苹果)。
注意的点
箭头函数 如果使用 {}
包裹函数体,则必须 显式地用 return
返回值。
- 箭头函数的块形式(使用
{}
)需要显式地写return
。 - 箭头函数的简洁形式(无
{}
)会自动返回表达式的值。
总的解释:
①使用reduce方法遍历数组
②reduce接收两个参数,一个回调函数,一个空数组
③回调函数传递了两个参数,一个是累加值,另一个是当前值
reduce的写法:
arrays.reduce((acc,cur,idx)=>{},[])