前言
很多方法之前都是用了就忘,记不住。有一个小技巧:通过整理归纳的方式,记忆会很深刻。而且,知道单词原来的意思,效果更好,比如splice,可以看下文中的翻译。
数组中改变原数组的方法
- arr.push(add1, add2...)
用法:在数组末尾添加n个元素,返回数组长度
var arr = []
arr.push(1,2,3,4,true,{})
// [1,2,3,4,true,{}]
- arr.pop()
用法:删除数组最后一个元素,并返回该元素。该方法没有参数
var arr = [1,2,3]
var item = arr.pop() // 3
- arr.shift()
翻译为去掉
用法:用于删除数组第一个元素,返回该元素。
var arr = [1,2,3]
var item = arr.shift() // 1
- arr.unshift(add1, add2...)
用法:数组前面插入n个元素,返回数组长度。
var arr = []
var length = arr.unshift(1,2,3) // 3
- arr.reverse()
翻译为翻转。
var arr = [1,2,3]
var newArr = arr.reverse() // [3,2,1]
- arr.sort(fn | 空)
如果参数为空,默认先把数组中的元素转成字符串,按照字符串对应的unicode位排序。所以不要用sort来排序,就算数字也不行。
var arr = [10,101]
var newArr = arr.sort() // [101, 11]
var arr = arr.sort((a, b) => a - b)
数组中不改变原数组的方法
- join('分隔符')
翻译为连接,
用法:表示用怎样的方式连接数组元素,返回一个字符串。默认参数为逗号
var arr = [1,2,3]
var str = arr.join() // '1,2,3'
- concat(arr | element1, element2...)
翻译为合并数组。
用法:参数为数组或其他类型都可以,如果是其他类型,那么会把这些元素插入到数组后面。返回一个合并后的数组。
var arr = [1,2,3]
var arr2 = [4,5,6]
var newArr = arr.concat(arr2) // [1,2,3,4,5,6]
newArr = arr.concat(7,8,9)
- arr.slice(start, end)
翻译:把...分成部分。
用法:返回一个数组,用于提取原数组中的部分。如果省略第二个参数。表示切割停止位置在数组末尾。如果参数为负数,那么代表倒数。默认参数为0,可以直接浅拷贝原数组。
var arr = [1,2,3]
newArr = arr.slice(-2, -1) // [2]
- arr.splice(start, count, add1, add2....)
翻译:绳子捻接、胶片粘接。可以想像成一条胶带在某个位置切断一段,然后可以在断点处加上一段。
返回值为一个数组,里面的元素是删除的元素。
var arr = [1,2,3]
newArr = arr.splice(0, 1, 4,5,6) // [4,5,6,2,3]
- map(fn, context)
用法:参数两个,第一个为函数,第二个为this指向。返回一个数组。
var arr = [1,2,3]
var arr2 = [4,5,6]
var newArr = arr.map(function (item, idx) {
return this[idx]
}, arr2)
forEach(fn, context)
用法:用法和map完全一样。返回一个数组。
注意点:用法和map完全一样。注意在forEach中无法中断。filter(fn, context)
用法:用法和forEach、map完全一样。返回一个数组。some(fn)、every(fn)
用法:参数和map、forEach、filter一样。返回值为true/false
var arr = [1,2,3]
arr.some((item) => item > 2) // true
var arr = [1,2,3]
arr.every((item) => item > 2) // false
- reduce(fn)、reduceRight(fn)
var arr = [1,2,3]
arr.reduce((prev, cur, idx, arr) => {
return prev - cur
}) // 1 - 2 - 3
var arr = [1,2,3]
arr.reduceRight((prev, cur) => {
return prev - cur
}) // 3 - 2 - 1
indexOf(ele, position)、lastIndexOf(ele, position)
注意,第二个参数表示从第几个元素开始找。返回值为数组的可以进行链式调用。
改变原数组方法(8)
traverse、push、pop、shift、unshift、sort、join、splice
没有改变原数组方法(11)
slice、map、forEach、filter、some、every、reduce、reduceRight、concat、indexOf、lastIndexOf
返回值为数组的方法
map、filter、splice、slice、concat、sort、reverse
数组查找元素的方法(6)
[1,2,3].some(x => x === 1) // true 找到该元素就不再循环,
[1,2,3].filter(x => x === 1).length //[1] 判断数组长度是否大于0
[1,2,3].find(x => x === 1) // true
[6,2,3].findIndex(x => x === 6) // 0 返回索引
[1,2,3].includes(1) //true
[6,2,3].indexOf(6) // 0 返回索引
忘记点
不改变原数组的:concat
reduce
先看redux中的compose函数实现
function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
用法
function fn1(x) {
console.log('a')
return x + 1
}
function fn2(x) {
console.log('b')
return x + 2
}
function fn3(x) {
console.log('c')
return x + 3
}
function fn4(x) {
console.log('d')
return x + 4
}
let composedFn = compose(fn1,fn2,fn3,fn4)
let result = composedFn(1)
console.log(result)
解析
// 第一次:a:fn1, b:fn2,也就是fn2执行了,将函数返回值传给fn1
// 第二次:a: (...args) => { return fn1(fn2(...args)) }, b: fn3, 现在我将前面这个函数叫做x
// 第三次:a: (...args) => x(fn3(...args)), b: fn4,现在我将前面这个函数叫做y,也就是返回(...args) => {return y(fn4(...args))},赋值到composedFn上
// 现在执行composedFn,流程就很清楚了。
function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => {
return (...args) => { // 这个args用来获取前一次函数执行的返回值
return a(b(...args)) // 这个args用来获取第一次传进来的参数
}
})
}
自己实现compose
function compose2(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return (...args) => {
const lastFn = funcs.pop()
return funcs.reduceRight((a, b) => { // a就是每次的返回值,b就是从后到前每个函数
return b(a)
}, lastFn(...args))
}
}
let composedFn2 = compose2(fn1,fn2,fn3,fn4)
let result2 = composedFn2(1)
console.log(result2)
// 用箭头函数不直观
function compose3(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return (...args) => funcs.reduceRight((a, b) => b(a), funcs.pop()(...args))
}
reduce实现
Array.prototype.reduce = function (fn, prev) {
const len = this.length
const argLen = arguments.length
if (len === 0) {
throw new TypeError('Reduce of empty array with no initial value')
}
if (len === 1 && argLen < 2) {
return this[0]
}
for (let i = 0; i < len; ++i) {
if (i === 0) {
if (argLen > 1) {
prev = fn(prev, this[i], i, this)
} else {
prev = fn(this[i], this[i+1], i+1, this)
}
} else {
prev = fn(prev, this[i+1], i+1, this)
}
if (len === 1) { // 当前数组只有一个元素,并且传了初始值的情况
return prev
}
if (i === len - 2) {
return prev
}
}
};
let result = [].reduce((a, b, i, arr) => {
console.log(a,b,i)
return a + b
})
console.log(result)
上面的实现有以下几个注意点:
- 考虑数组长度为0的情况
- 考虑当前数组长度为1,但是有第二个参数的情况
- 考虑首次执行时,有无第二个参数的情况