对数组的处理有很多的方法,但是每次做有数组的需求的时候,总局限于初级的水平,说到数组的处理大家首先想到的是会想到如何对做数组
创建、增、删、改、查
,其次for循环
,了解了这些基本大部分的需求就可以解决了,但是这里面还有很多细节,可以大大减少工作量
一、Array构造器(数组的创建)
// 使用Array构造器
var a = Array(6); // [undefined × 6]
//这里使用Array(6)和new Array(6)都可以,Array构造器内部对this指针的判判断
function Array(){
// 如果this不是Array的实例,那就重新new一个实例
if(!(this instanceof arguments.callee)){
return new arguments.callee();
}
}
// 使用对象字面量
var arr = [];
arr.length = 6;// [undefined × 6]
ES6新增的构造函数方法
鉴于数组的常用性,ES6专门扩展了数组构造器Array ,新增2个方法:Array.of、Array.from。
- Array.of用于将参数依次转化为数组中的一项,然后返回这个新数组
var arr = Array.of(8.0,9,10)
console.log(arr)//[8,9,10]
- Array.from的设计初衷是快速便捷的基于其他对象创建新数组,准确来说就是从一个类似数组的可迭代对象创建一个新的数组实例。
//类数组转化成数组
Array.from(map1)//ES6为Array增加了from函数用来将其他对象转换成数组。
Array.prototype.slice.call()//Array.prototype.slice.call()能把类数组对象转化成数组
document.getElementsByClassName('tool-bar-wrapper') instanceof Array //false
Array.from(document.getElementsByClassName('tool-bar-wrapper')) instanceof Array //false
//Array.from拥有3个形参,第一个为类似数组的对象,必选。第二个为加工函数,新生成的数组会经过该函数的加工再返回。第三个为this作用域,表示加工函数执行时this的值。
var obj = {0: 'A', 1: 'M', 2:'Y', length: 3};
Array.from(obj, function(value, index){
console.log(value, index, this, arguments.length);
return value.repeat(2); //必须指定返回值,否则返回undefined
}, obj);
//A 0 {0: "A", 1: "M", 2: "Y", length: 3} 2
// M 1 {0: "A", 1: "M", 2: "Y", length: 3} 2
//Y 2 {0: "A", 1: "M", 2: "Y", length: 3} 2
//["AA", "MM", "YY"]
二、数组的增删改查
数组元素的添加
push : 将一个或多个新元素添加到数组结尾,并返回数组新长度
unshift : 将一个或多个新元素添加到数组开始,数组中的元素自动后移,返回数组新长度
splice :将一个或多个新元素插入到数组的指定位置,插入位置的元素自动后移
var a =['a','b','c','d']
a.push('f','s')
console.log(a)//['a','b','c','d','f','s']
a.unshift("Amy")
console.log(a)//["Amy", "a", "b", "c", "d"]
a.splice(1,0,'Amy')
console.log(a) // ["a", "Amy", "b", "c", "d"]
数组元素的删除
pop : 先进后出,移除最后一个元素并返回该元素值
shift : 先进先出 ,移除最前一个元素并返回该元素值,数组中元素自动前移
splice :删除从指定位置开始的指定数量的元素,数组形式返回所移除的元素
var b =['e','f','g','k']
b.pop()
console.log(b) // ['e','f','g']
console.log(b.shift()) // e
console.log(b) // ['f','g','k']
b.splice(1,1)
console.log(b) //['e','g','k']
数组元素的修改
数组元素的修改,可就多了:
var c =[1,2,3,4,5]
var d =[5, 4, 3, 2, 1]
//concat 数组的拼接
console.log(c .concat(d)) // [1, 2, 3, 4, 5, 5, 4, 3, 2, 1]
//concat 数组的拷贝
var conArr = c.concat()
console.log(conArr)//生成[1, 2, 3, 4, 5]的新数组
//slice 数组的截取
console.log(c.slice(1,3)) // [2, 3]
//slice 数组的拷贝
var sliceArr = c.slice(0)
console.log(sliceArr)//生成[1, 2, 3, 4, 5]的新数组
//数组元素的排序
// reverse倒序
console.log(c.reverse())
//sort正序倒序
console.log(c.sort(function(a,b){
return b - a
})) //从大到小倒序[5, 4, 3, 2, 1]
console.log(c.sort(function(a,b){
return b - a
})) //从小到大正序[1, 2, 3, 4, 5]
//indexOf来搜索一个指定的元素的位置
console.log(c.indexOf(6))// 元素6的索引为-1 就是没有
// lastIndexOf返回在数组中搜索到的与给定参数相等的元素的最后(最大)索引
console.log(c.lastIndexOf(3)) //2
//join()方法是一个非常实用的方法,它把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串
console.log(c.join('|')) //'1|2|3|4|5'
//split() 方法用于把一个字符串分割成字符串数组。
var k = '1|2|3|4|5'
console.log(k.split('|'))
//toString把数组转换为字符串,并返回结果。
console.log(a.toString()) // '1,2,3,4,5'
console.log(new Date().toString()) // Thu Jul 19 2018 14:34:16 GMT+0800 (China Standard Time)
//toLocaleString方法可根据本地时间把 Date 对象转换为字符串,并返回结果。
console.log(c.toLocaleString()) // '1,2,3,4,5'
console.log(new Date().toLocaleString())//7/19/2018, 2:33:23 PM
//valueOf() 方法可返回 Boolean 对象的原始值
console.log(c.valueOf()) //[1, 2, 3, 4, 5]
数组元素的查看
var b =['e','f','g','k']
console.log(b[0])//'e'
三、判断是否是数组
var a = [];
// 1.基于instanceof
a instanceof Array;
// 2.基于constructor
a.constructor === Array;
// 3.基于Object.prototype.isPrototypeOf
Array.prototype.isPrototypeOf(a);
// 4.基于getPrototypeOf
Object.getPrototypeOf(a) === Array.prototype;
// 5.基于Object.prototype.toString
Object.prototype.toString.apply(a) === '[object Array]';
四、遍历方法
1、常用的for循环
for (var index = 0; index < myArray.length; index++) {
console.log(myArray[index]);
}
return false(只能在函数中使用否则报错)和break跳出循环
continue // 跳过本次循环,继续下一个循环
2、forEach(ES5新增)
break跳出循环回报错,return false 跳出本次循环 forEach()遍历数组时要如何才能跳出循环呢: 1、try catch 2、第二种方法:使用arr.some() return true或者arr.every()return false替代
自从JavaScript5起,我们开始可以使用内置的forEach
方法:
var eArr = [0,1,2,3]
var nArr = eArr.forEach((item,index,arr)=>{
eArr[index] = item * item;
})
console.log(eArr) // [0, 1, 4, 9] 改变原数组
console.log(nArr) // undefined
3、for-of
JavaScript6里引入了一种新的循环方法,它就是for-of循环,它既比传统的for循环简洁,同时弥补了forEach和for-in循环的短板。
可以循环一个数组Array、字符串、类型化的数组(TypedArray)、Map、Set、 DOM collection:
4、filter() 方法使用传入的函数测试所有元素,并返回所有通过测试的元素组成的新数组。它就好比一个过滤器,筛掉不符合条件的元素。
语法:arr.filter(fn, thisArg)(ES5新增)
var array = [18, 9, 10, 35, 80];
var array2 = array.filter(function(value, index, array){
return value > 20;
});
console.log(array2); // [35, 80]
手动实现
Array.prototype._filter = function(callback){
if(typeof callback !== 'function') throw new Error(`${typeof callback} is not a function`)
let result = [];
for(let i=0;i<this.length;i++){
callback && callback(this[i],i,this) && result.push(this[i])
};
return result;
};
[1,3,4]._filter((item)=>item>2);
5、reduce()和 reduceRight() (ES5新增)
reduce() 方法接收一个方法作为累加器,数组中的每个值(从左至右) 开始合并,最终为一个值。
reduceRight()则从数组的最后一项开始,向前遍历到第一项。
语法:arr.reduce(fn, initialValue)
fn 表示在数组每一项上执行的函数,接受四个参数:
previousValue 上一次调用回调返回的值,或者是提供的初始值
value 数组中当前被处理元素的值
index 当前元素在数组中的索引
array 数组自身
initialValue 指定第一次调用 fn 的第一个参数。
var array = [1, 2, 3, 4];
var s = array.reduce(function(previousValue, value, index, array){
return previousValue * value;
},1);
console.log(s); // 24
// ES6写法更加简洁
array.reduce((p, v) => p * v); // 24
手动实现
Array.prototype._reduce = function(callback,initVal){
if(typeof callback !== 'function') throw new Error(`${typeof callback} is not a function`)
let result = initVal|| this[0];
for(let i=0;i<this.length;i++){
result = callback(result,this[i],i,this);
};
return result;
};
[1,2,3].reduce((total,item)=>total+=item,0)
every(ES5新增)
判断数组中是否每个元素都满足条件
只有都满足条件才返回true;
只要有一个不满足就返回false;
arr.every(function(value,index,array){return 条件})
Array.prototype._every = function(callback){
if(typeof callback !== 'function') throw new Error(`${typeof callback} is not a function`)
let result = true;
for(let i=0;i<this.length;i++){
if(!callback(this[i])){
result = false;
break
}
};
return result;
};
[1,2,3]._every((item)=>item>=1);
some(ES5新增)
判断数组中是否至少有一个元素满足条件
只要有一个满足就返回true
只有都不满足时才返回false
arr.some(function(value,index,array){return 条件})
Array.prototype._some = function(callback){
if(typeof callback !== 'function' ){
throw new Error(`${typeof callback} is not a function`)
}
let result = false;
for(let i=0; i<this.length; i++){
if(callback(this[i], i, this)){
result = true;
break;
}
}
return result
};
[1,2,3]._some((item)=>item>3)
find
返回第一个出现的元素
[1,2,3].find((item)=>item>1)
Array.prototype._find = function(callback){
if(typeof callback !== 'function') throw new Error(`${typeof callback} is not a function`)
let result;
for(let i=0;i<this.length;i++){
if(callback(this[i])){
result = this[i];
break
}
};
return result;
};
[1,2,3]._find((item)=>item>1)
map(ES5新增)
返回第一个出现的元素
[1,2,3].map((item)=>item*2)
Array.prototype._map= function(callback){
if(typeof callback !== 'function') throw new Error(`${typeof callback} is not a function`)
let result = [];
for(let i=0;i<this.length;i++){
callback && result.push(callback(this[i],i,this))
};
return result;
};
[1,3,4]._map((item)=>item*2)
Array.splice(开始下标, 删除的个数,元素)(该方法会改变原始数组)
splice():很强大的数组方法,它有很多种用法,可以实现删除、插入和替换。
splice()方法始终都会返回一个数组,该数组中包含从原始数组中删除的项,如果没有删除任何项,则返回一个空数组。
Array.slice(开始下标, 结束下标)不改变元素组
slice():返回从原数组中指定开始下标到结束下标之间的项组成的新数组。slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。
join(separator): 将数组的元素组起一个字符串,以separator为分隔符,省略的话则用默认用逗号为分隔符,该方法只接收一个参数:即分隔符。
push()和pop()
push(): 可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。
pop():数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。
shift() 和 unshift()
shift():删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined 。
unshift:将参数添加到原数组开头,并返回数组的长度 。
sort()
sort():按升序排列数组项——即最小的值位于最前面,最大的值排在最后面。(元数组被改变)
reverse()
reverse():反转数组项的顺序。(元数组被改变)
concat()
concat() :将参数添加到原数组中。这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本。(原数组未被修改)
indexOf(要查找的项,查找起点位置)和 lastIndexOf(要查找的项,查找起点位置) (ES5新增)
indexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找。
lastIndexOf:接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找。
var arr = [1,3,5,7,7,5,3,1];
console.log(arr.indexOf(5)); //2
console.log(arr.lastIndexOf(5)); //5
console.log(arr.indexOf(5,2)); //2
console.log(arr.lastIndexOf(5,4)); //2
console.log(arr.indexOf("5")); //-1
五、es6新增方法
//es6扩展运算符
[...'hello']//['h','e','l','l','o']
// fill with 0 from position 2 until position 4-1
var array1 = [1,2,3,4,5]
console.log(array1.fill(0, 2, 4)); //[1,2,0,0,5]
// Array.prototype.copyWithin(target, start = 0, end = this.length)
// 将 3 号位复制到 0 号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4) //[4, 2, 3, 4, 5]
//find&findIndex(ES6)
var array = [1, 3, 5, 7, 8, 9, 10];
function f(value, index, array){
return value%2==0; // 返回偶数
}
function f2(value, index, array){
return value > 20; // 返回大于20的数
}
console.log(array.find(f)); // 8
console.log(array.find(f2)); // undefined
console.log(array.findIndex(f)); // 4
console.log(array.findIndex(f2)); // -1
网友评论