如何判断一个对象是数组
var arr = []
console.log(arr instanceof Array)//true复制代码
数组操作方法
1.indexOf()
返回在数组中找到的第一个元素对应的索引,如果不存在,返回-1
var arr = [2,3,1,5,4,3,7];
console.log(arr.indexOf(5)) // 3
console.log(arr.indexOf(10))// -1复制代码
扩展 判断数组中是否包含某元素
var arr1 = [1,5,6,6]
Array.prototype.contains=function(obj) {
return (this.indexOf(obj) >= 0);
}
console.log(arr1.contains(6)) //true
console.log(arr1.indexOf(6)) //2
复制代码
2.sort()
sort()方法是默认为按照ASCII码进行顺序排序。在使用sort()方法时,会先隐性调用toString()方法将数组中的每一项进行字符串转化,实际上是进行字符串ASCII进行排序,并返回排序后的数组。
对于数组项中均为number类型的数据,我们可以在sort()中传入一个比较函数,该比较函数接收两个参数,第一个参数为前一项,第二个参数为后一项。将两个参数进行对比,若return的值>0,则将两个对比项进行调换位置,调换位置的项,再与较前的一项进行对比,依次类推,直到return值返回为0或者<0为止。
在比较函数中,return值>0,数组项调换位置;return值<0,数组项不调换位置;return值=0,意味着两项相等,数组项不调换位置。
var arr1 = [3,20,9,114,1,2];
arr1.sort(function(a,b){
return a-b;
});
console.log(arr1);//[1, 2, 3, 9, 20, 114]
复制代码
3.filter()
对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组,它利用指定的函数确定是否在返回的数组中包含某一项
var arr = [1,2,3,4,5,4,3,2,1];
var arr1 = arr.filter(function(item, index, array){
return (item > 2);
});
console.log(arr1);
// [3, 4, 5, 4, 3] 就如filter的意思(过滤),返回数组元素大于2的数组元素,过滤掉小于2的元素。复制代码
4.forEach(callback[thisArg])
var arr = ['a','b','c'];
arr.forEach(function(item,index,obj){
console.log(item,index,obj);
})
//
a 0 ["a", "b", "c"]
b 1 ["a", "b", "c"]
c 2 ["a", "b", "c"]
复制代码
从输出的接口可以看出,callback中传入了3个参数item,index,obj 分别表示当前元素、当前位置、数组对象。 再看看使用thisArg的情况
var obj = {
fn:function(a,b){
console.log(a,b);
}
};
var arr = ['a','b','c'];
arr.forEach(function(v,i,a){
console.log(this)
//
window
window
window
});
复制代码
var obj = {
fn:function(a,b){
console.log(a,b);
// a 0
// b 1
// c 2
}
};
var arr = ['a','b','c'];
arr.forEach(function(v,i,a){
console.log(this)
// {fn: ƒ}
// {fn: ƒ}
// {fn: ƒ}
this.fn(v,i);
},obj);复制代码
不传thisArgs时,callback中的 this 默认指向window对象,当传递thisArg时,callback中的this就指向了thisArg,因此这个参数的目的就是为了改变回调函数中的this指向。
5.unshift()
var arr1 = [5,8,9,6,2]
console.log(arr1.unshift(0)) //6
console.log(arr1)//[0, 5, 8, 9, 6, 2]
复制代码
6.reduce()
语法:
array.reduce(callback,[initialValue]) //注意这时候只能是同步方法复制代码
function callback (preValue, curValue, index, array)复制代码
preValue
: 上一次调用回调返回的值,或者是提供的初始值(initialValue)
curValue
: 数组中当前被处理的数组项
index
: 当前数组项在数组中的索引值
array
: 调用
reduce()
方法的数组
而initialValue
作为第一次调用 callbackfn
函数的第一个参数著作权归作者所有。
reduce()
方法为数组中的每一个元素依次执行回调函数callbackfn
,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce()
的数组。
回调函数第一次执行时,preValue
和 curValue
可以是一个值,如果 initialValue
在调用 reduce()
时被提供,那么第一个 preValue
等于 initialValue
,并且curValue
等于数组中的第一个值;如果initialValue
未被提供,那么preValue
等于数组中的第一个值,`curValue等于数组中的第二个值。
var arr = [0,1,2,3,4]; arr.reduce(function (preValue,curValue,index,array) {
return preValue + curValue;
}); // 10复制代码
回调函数被执行四次,每次参数和返回的值如下:
preValue | curValue | index | array | 返回值 | |
---|---|---|---|---|---|
第一次回调 | 0 | 1 | 1 | [0,1,2,3,4] | 1 |
第二次回调 | 1 | 2 | 2 | [0,1,2,3,4] | 3 |
第三次回调 | 3 | 3 | 3 | [0,1,2,3,4] | 6 |
第四次回调 | 6 | 4 | 4 | [0,1,2,3,4] | 10 |
上面的示例reduce()
方法没有提供initialValue
初始值,接下来再上面的示例中,稍作修改,提供一个初始值,这个值为5
。这个时候reduce()
方法会执行五次回调,每次参数和返回的值如下:著作权归作者所有。
var arr = [0,1,2,3,4]; arr.reduce(function (preValue,curValue,index,array) {
return preValue + curValue;
}, 5); //15
复制代码
preValue | curValue | index | array | 返回值 | |
---|---|---|---|---|---|
第一次回调 | 5 | 0 | 0 | [0,1,2,3,4] | 5 |
第二次回调 | 5 | 1 | 1 | [0,1,2,3,4] | 6 |
第三次回调 | 6 | 2 | 2 | [0,1,2,3,4] | 8 |
第四次回调 | 8 | 3 | 3 | [0,1,2,3,4] | 11 |
第五次回调 | 11 | 4 | 4 | [0,1,2,3,4] | 15 |
7.map()
数组map 方法
Array.prototype.map(callback[,thisArg]);
【功能】
依次迭代数组中的元素,在callback中处理后,返回一个新的数组;
forEach和map一样,都会依次迭代数组中的元素,不同的是forEach
并不会返回一个新数组,而map会返回一个新的数组;
复制代码
map 接受两个参数,第一个是回调函数,第二个控制回调函数中this的指向;
1.callback(item,index,arr);
接受3个参数,第一个‘item’,为当前迭代的数组中的元素,‘index’为当前迭代元素的下标,‘arr’为原数组;
2.thisArg
默认callback中的this是指向window的,可以通过设置every的第二个参数,改变callback中this的指向;
let arr1 = [1,2,6,3,4,5];
let arr2 = arr1.map(function(item,index,arr){
console.log(this); //window
return item + 1;
});
console.log(arr2);//[2, 3, 7, 4, 5, 6]复制代码
let arr1 = [1,2,6,3,4,5];
let arr2 = arr1.map(function(item,index,arr){
console.log(this); //[1, 2, 6, 3, 4, 5]
return item + 1;
},arr1); console.log(arr2);//[2, 3, 7, 4, 5, 6]
复制代码
8.includes
Array.prototype.includes
方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes
方法类似。
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true复制代码
该方法的第二个参数表示搜索的起始位置,默认为0
。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4
,但数组长度为3
),则会重置为从0
开始。
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, 2); // true
[1, 2, 3].includes(3, -1); // true复制代码
问题1
判断一个数最接近数组中的某个数
var arr1 = [10, 16, 7, 8, 6, 2];
var oNum1 = 5
var oNum2 = arr1.sort(function(a, b) {
return Math.abs(a - oNum1) - Math.abs(b - oNum1);
})[0];
console.log(oNum2) // 6
复制代码
问题2 数组去重
ES6方法
var arr = [4,89,65,75,89,89,67,89]
console.log([...new Set(arr)]) //[4, 89, 65, 75, 67]
复制代码
const arr1 = [4,89,65,75,89,89,67,89]
let arr2 = arr1.filter(function(item,index){
return index === arr1.indexOf(item);
});
console.log(arr2) //[4, 89, 65, 75, 67]
改成箭头函数的写法
const arr1 = [4,89,65,75,89,89,67,89]
let arr2 = arr1.filter((item,index) => {
return index === arr1.indexOf(item);
});
console.log(arr2) //[4, 89, 65, 75, 67]
复制代码
优点:
与用 for 循环方式实现,这2种方式有以下优点:
- 更易读;
- 代码量小;
- 不用创建额外的临时变量;
- 性能稍微更快;
注意:
- 该方法不改原数组,会返回一个新的数组;
- 该方法是通过 严格相等
===
运算符来判断 数组的元素是否重复的;
在数组原型上添加该方法
const arr1 = [4,89,65,75,89,89,67,89]
Array.prototype.getNoRepeats = function (){
return this.filter(function(item,index,arr){
return index === arr.indexOf(item);
});
}
console.log(arr1.getNoRepeats()) //[4, 89, 65, 75, 67]
复制代码
遍历
let arr1 = [1,5,5,6,7,7,9,8,5]
const unqique = (arr) => {
var obj = {}
arr.forEach(value => {
obj[value] = 0;
遍历newA是否存在key,如果存在key会大于0就跳过push的那一步
})
return Object.keys(obj)
}
console.log(unqique(arr1)) //) ["1", "5", "6", "7", "8", "9"]复制代码
遍历,将数组的值添加到一个对象的属性名里,并给属性赋值,对象不能添加相同属性名,以这个为依据可以实现数组去重,然后用Object.keys(对象)
返回这个对象可枚举属性组成的数组,这个数组就是去重后的数组。
问题3 取出两个数组的相同项
let arr1 = [1,3,4,5];
let arr2 = [1,4,6];
let getSome = arr1.filter(item=>{
return arr2.includes(item)
});
console.log(getSome); // [1,4]复制代码