一、针对Array对象做了大幅拓展
1、Array.isArray(obj)
用于判断一个变量(或对象)是否为数组,如:1
2
3
4
5Array.isArray([])
// true
Array.isArray({})
// false
2、.indexOf(element)
/ .lastIndexOf(element)
用于如何判断在一个数组中找到所看到的一个值、数字,或变量是否存在
(1)ES3的做法:1
2
3
4
5
6
7
8
9
10
11
12
13 var arr = [3, 4, 'hello' ,'wangxiaoqin']
// undefined
function hasWord(arr,item){ for(var i=0; i<arr.length; i++){
if(arr[i] === item)
return true
}
return false
}
// undefined
hasWord(arr,'wangxiaoqin')
// true
hasWord(arr,'helloo')
// false
(2)ES5的拓展做法1
2
3
4
5
6var arr = [3, 4, 'hello' ,'wangxiaoqin']
// undefined
arr.indexOf('wangxiaoqin')
// 3
arr.indexOf('wanxiaoqin')
// -1 //写了一个不存在的,直接输出-1
总结:
那么,依此可以得出,-1
也可以作为判断某对象是否存在于该数组
3、.forEach(element,index,arrary)
遍历一个数组,可以使用for循环;也可以数组自带的.forEach
1
2
3
4
5
6
7
8
9
10
11var arr = [3, 4, 'hello' ,'wangxiaoqin']
// undefined
arr
--> (4) [3, 4, "hello", "wangxiaoqin"]
arr.forEach(function(){
console.log(arguments)
})
-->Arguments(3) [3, 0, Array(4),
Arguments(3) [4, 1, Array(4),
Arguments(3) ["hello", 2, Array(4),
Arguments(3) ["wangxiaoqin", 3, Array(4),
图:
接着,可以使用.forEach
遍历该数组1
2
3
4
5
6
7
8arr.forEach(function(value,index){ //value指数组中的元素,index指数组中的下标
console.log(''+value+value)
})
-->33
44
hellohello
wangxiaoqinwangxiaoqin
//undefined
4、.every(function(element, index, array))
用于满足该数组中函数设定的某个条件,函数返回的是一个布尔值
满足条件:
- every是所有函数的每个回调函数都返回true的时候才会返回true,当遇到false的时候终止执行,返回false
- some函数是“存在”有一个回调函数返回true的时候终止执行并返回true,否则返回false
如:1
2
3
4[3,4,-1,0,5].every(function(val){
return val>0?true:false //使用三目运算符 === if...else
})
// false
.some(function(element,index,array))
只要有一个符合,那就返回true;反之,则..
5、.map(function(element))
对数组中每一元素进行处理,函数返回值组成一个新数组返回,新数组索引结构和原数组一致,原数组保持不变。1
2
3
4
5
6var arr2 = [1, 2, 3, 4, 5, 6].map(function(val){
return val*val
})
// undefined
arr2
// (6) [1, 4, 9, 16, 25, 36]
6、1
2
3
4
5
数组的过滤。
**注:**
产生新数组,原数组保持不变,如:
1 | 数组的过滤。 |
var arr=[3, 5, 6, -1, -2, -3]
// undefined
arr.filter(function(val){
return val>0
})
// (3) [3, 5, 6] //产生新数组
arr
// (6) [3, 5, 6, -1, -2, -3] //原数组不变
/ 所以,我们需要为新数组赋新变量 /
var arr2 = arr.filter(function(val){
return val>0
})
// undefined
arr2
// (3) [3, 5, 6]
/ 如需过滤出里面的负数 /
var arr3 = arr.filter(function(val){
return val <0
})
// undefined
arr3
// (3) [-1, -2, -3]1
再如:
var students = [
{
name:’ad’,
age:10
},
{
name:’bb’,
age:20
},
{
name:’ca’,
age:8
},
{
name:’ce’,
age:5
},
]
/ 假设过滤出数组里年纪大于18岁的 /
var age18 =
students.filter(function(students){
return students.age > 18
})
console.log(age18)
--> [[object Object] {
age: 20,
name: "bb"hui
}
]
/ 假设过滤出数组里姓名里带有“c” /
var namehasc =
students.filter(function(students){
return students.name.indexOf(‘c’)>-1
})
console.log(namehasc)
–>[[object Object] {
age: 8,
name: “ca”
}, [object Object] {
age: 5,
name: “ce”
}]1
2
3
4以此,可以通过过滤可进行排序、查找、单独的处理
### 7、`.reduce(function(v1, v2), value)`
两元素(或参数)执行操作,数组元素返回组合成一个值,遍历数组,继续和数组中 其他元素组合,最终得出结果。代码如下:
var arr = [3, 4, 5]
–> undefined
arr.reduce(function(v1,v2){
return v1 + v2
})
–> 12 //7+5
arr.reduce(function(v1,v2){
return v1 v2
})
–> 60 //125
/ 使用初始值 .reduce(function(v1, v2), value) value为初始值 /
arr.reduce(function(v1,v2){
return v1 + v2 },100)
–> 112
//100(v1)+3(v2)+4+5
//103(v1)+4(v2)+5
以此类推1
2
3
4
5
6
7
8
# 二、学习
### 1、手写reduce功能
A、先补充一些基本JS知识,
假设:想要克隆一个与`arr`完全一样的`arr2`,但二者互不相干,如何处理?通过使用concat方法,一个数组arr拼接另一个数组,然后得到一个新的数组`arr2`。即通过concat获得一个新数组,拼接的原数组保持不变。实现一个**深拷贝**。
**注:[ ]空数组也是一个数组**
arr = [1,2,3]
// [1, 2, 3]
arr2 = arr.concat([])
// [1, 2, 3]
arr2
// [1, 2, 3]
/ 测试一下是否二者有关联 /
arr2[0] = 100
// 100
arr
// [1, 2, 3]
arr2
// [100, 2, 3]1
2
B、手写一个reduce功能
function reduce(arr, fn, initValue){
var arr2 = arr //===[3, 4, 5, 6]
while(arr2.length > 1)
}
//第2:如何是实现reduce?计划通过处理arr2 = [3, 4, 5, 6]的v1,v2, 通过function(v1,v2){return v1+v2}处理,依次循环得出结果
var arr = [3, 4, 5, 6]
var result = reduce(arr, function(v1,v2){
return v1+v2 //第1:通过此遍历arr数组
},10)1
取消初始值去做:
function reduce(arr, fn){
var arr2 = arr //===[3, 4, 5, 6]
while(arr2.length > 1){
console.log(arr2)
arr2.splice(0,2,fn(arr2[0],arr2[1]))
}
return arr2[0]
} //第3:while(arr2.length > 1) 相当于设置一个条件:当这个数组有两个以上的值时,
//第4:arr2 === arr用fn函数进行处理,v1+v2相加替换成一个结果, 使用splice(位数,个数,替换的结果),依次类推得出arr2 === arr的结果
var arr = [3, 4, 5, 6]
//[7,5,6]
//[12,6]
//[18]
var result = reduce(arr, function(v1,v2){
return v1+v2
})
console.log(result)
//输出结果
-->[3, 4, 5, 6]
[7, 5, 6]
[12, 6]
18
1 | 图: |
function reduce(arr, fn,initValue){
var arr2 = arr.concat([]) //===[3, 4, 5, 6]
if(initValue !== undefined){ //这里注意 === 会出现报错
arr2.unshift(initValue)
}
//不等于undefined,表示用户传递了这个initValue参数
while(arr2.length > 1){
console.log(arr2)
arr2.splice(0,2,fn(arr2[0],arr2[1]))
}
return arr2[0]
}
var arr = [3, 4, 5, 6]
var result = reduce(arr, function(v1,v2){
return v1 + v2 },10)
console.log(result)
//输出值:
–> [10, 3, 4, 5, 6]
[13, 4, 5, 6]
[17, 5, 6]
[22, 6]
281
2
3图:
![image](https://user-gold-cdn.xitu.io/2018/8/15/1653d54a94b9cf5e?w=600&h=348&f=jpeg&s=30881)
或者减少代码量,采用三目运算符的方法来设置初始值:
function reduce(arr, fn,initValue){
var arr2 =
(initValue !== undefined?[]:[initValue]).concat(arr)
while(arr2.length > 1){
console.log(arr2)
arr2.splice(0,2,fn(arr2[0],arr2[1]))
}
return arr2[0]
}
var arr = [3, 4, 5, 6]
var result = reduce(arr, function(v1,v2){
return v1 + v2 },10)
console.log(result)
//输出值
–> [3, 4, 5, 6]
[7, 5, 6]
[12, 6]
181
2
3
4
5
6
7图:
![image](https://user-gold-cdn.xitu.io/2018/8/15/1653d54a94b5b19f?w=600&h=283&f=jpeg&s=23154)
### 2、将一个数组拍平
对一个无限次嵌套的数组进行拍平,如何处理?
例子1:这道题也可以作为一个初级JS的思考,每次不会做的话,先从这道题的基本思考方式来看
var arr = [3, [‘4,5’,7,[1]], [2,10] ]
function flat(){
} //重点解决这一块的逻辑,即最终返回一个新的数组
var arr2 = flat(arr)
console.log(arr2)
var arr = [3, [‘4,5’,7,[1]], [2,10] ]
function flat(arr){
var arr2 = []
arr.forEach(function(val){
if(Array.isArray(val)){
arr2 =arr2.concat(flat(val))
}else{
arr2.push(val)
}
})
return arr2//不是数组的话就返回 }
/ flat(arr)就是将一个数组拍平,变成一个普通数组,对arr里进行判断, 如果不是个数组(如3),则放在 var arr2 = []里的空数组里, 如果是数组的,即 [‘4,5’,7,[1]],则把其放在这个arr.forEach(function(val){})数组里执行,则 重点解决函数这一块的逻辑 :
1、定义一个要返回的数组arr2
2、遍历原始数组arr,且用函数遍历arr的每一项
2.1 if判断是否为数组,采用Array.isArray判断。 若是数组,要处理嵌套数组,再次调用函数,将嵌套函数“拍平”,用递归法一一验证,最后得出结果
2.2 else如果不是数组,直接push在arr=[]里 /
var arr2 = flat(arr) console.log(arr2)
//输出结果
–> [3, “4,5”, 7, 1, 2, 10]1
2
3
例子2:
实现一个flatten函数,将一个嵌套多层的数组arry(数组)(嵌套可以是任何层数)转换成只有一层的数组,数组中元素仅基本类型的元素或数组,不存在循环引用的情况。如:
flatten([1,[2],[3,[[4]]])=> [1,2,3,4]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29```
var arr = [3,[2,-4,[5,7]],-3,['aa',[['bb']]]]
var arr2 = flatten2(arr)
console.log(arr2)
/* 方法1: */
function flatten(arr){
var newArr = []
function _flat(arr){
arr.forEach(val=>{ //对数组的每一项进行一个遍历 val=>,为匿名函数
if(Array.isArray(val)){
_flat(val)
}else{
newArr.push(val)
}
})
}
_flat(arr)
return newArr }
/* 方法2: */
function flatten2(arr){
return arr.reduce(function(initArr,currentArr){
return initArr.concat(Array.isArray(currentArr)?flatten2(currentArr):currentArr)
},[])
}
/*不是数组的话,就concat;如果是数组,则通过再次调用flatten2(Arr)拍平当前数组flatten2(currentArr) */