js数组方法
原生数组方法的描述
数组方法 | 参数描述 | 函数原理简述 | 原数组变化 | 返回值 |
---|---|---|---|---|
push | (需要插入的元素) | 添加一个或多个元素到数组的末尾 | 改变 | 操作后的数组长度 |
pop | 无 | 删除一个数组中的最后一个元素 | 改变 | 被删除的元素 |
shift | 无 | 删除数组的第一个元素,并返回这个元素 | 改变 | 被删除的元素 |
unshift | (需要插入的值) | 在数组的开头插入一个或多个元素 | 改变 | 数组长度 |
reverse | 无 | 前后颠倒数组中元素的位置,第一个元素会成为最后一个 | 改变 | 操作后数组 |
sort | (空/比较函数) | 对数组的元素做原地的排序,并返回这个数组。sort可能不稳定,默认按照字符串的unicode码位点排序 | 改变 | 操作后的原数组 |
splice | (开始索引,要删除数量,要插入值) | 在任意的位置给数组添加或删除任意个元素(拼接);拼接,拆分数组 | 改变 | 被删除的值(数组形式)无则为空数组 |
copyWithin | (开始索引,替代数组开始的索引/空[默认为0],替代数组结束的索引/空[默认为数组长度]) | 用于在数组内的替换操作,即替换元素和被替换元素都是数组内的元素 | 改变 | 操作后的原数组 |
concat | (需要拼接的数组) | 用于合并两个或多个数组 | 不变 | 操作后的数组 |
includes | (值,索引/查询起始位置) 用来判断当前数组是否包含某指定的值 | 不变 | 布尔值 | |
indexOf | (值,索引/查询起始位置) | 返回在数组中可以找到一个给定元素的第一个索引 | 不变 | 索引 |
lastIndexOf | (值,索引/查询起始位置) | 返回在数组中可以找到一个给定元素的最后一个索引,会从数组的后面向前查找 | 不变 | 索引 |
join | (连接符) | 将一个数组(或一个类数组对象)的所有元素连接成一个字符串 | 不变 | 连接后的字符串 |
slice | (开始索引,终止索引/不包含该位置) | 在任意的位置给数组添加或删除任意个元素(拼接) | 不变 | 按逻辑增删后的数组(不改变原数组) |
toString | 无 | 使数组变成字符串,用’,’连接。若数组的值存在数组,会便遍历拼接在字符串里;对象,会变成[object Object];undefined则什么都不连接,即会变成, | 不变 | 字符串 |
toLocalString | 无 | 使数组变成字符串,用’,’连接。数组内的元素会调用自己的toLocalString方法 | 不变 | 字符串 |
forEach | (callback(item/值,index/索引,array/原数组),v/callback执行的作用域) ) | forEach遍历的范围在第一次调用 callback前就会确定。调用forEach后添加到数组中的项不会被 callback访问到。如果已经存在的值被改变,则传递给 callback的值是 forEach遍历到他们那一刻的值。已删除的项不会被遍历到 | 不变 | 无 |
map | (callback(item/值,index/索引,array/原数组),v/callback执行的作用域)) | 一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组 | 不变 | 返回值构成的新数组 |
keys | 无 | 返回一个新的Array迭代器,它包含数组中每个索引的键 | 不变 | Array迭代器 |
values | 无 | 返回一个新的Array迭代器,它包含数组中每个值的键 | 不变 | Array迭代器 |
entries | 无 | 返回一个新的Array迭代器,它包含数组中每个键值对[index,item] | 不变 | Array迭代器 |
every | (callback(value,key,arr),v/callback执行的作用域)) | 若数组的值执行callback全部返回true,则最终返回true | 不变 | 布尔值 |
some | (callback(value,key,arr),v/callback执行的作用域)) | 若数组的值执行callback有一个返回true,则最终返回true | 不变 | 布尔值 |
filter | (callback(value,key,arr),v/callback执行的作用域)) | 使用指定的函数测试所有元素,并创建一个包含所有测试通过的元素的新数组 | 不变 | 使callback返回true的值组成的数组 |
find | ((callback(v,k,a),v/callback执行的作用域) ) | 返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。 | 不变 | 通过测试的第一个元素值或undefined |
findIndex | ((callback(v,k,a),v/callback执行的作用域) ) | 返回数组中满足提供的测试函数的第一个元素的值的索引。否则返回 undefined。 | 不变 | 通过测试的第一个元素值的索引或undefined |
reduce | (callback(p/上一次回调的返回值,v/当前被处理的元素,i/索引,a/原数组)=> {},initialValue初始值) | 该方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值 | 不变 | 最后的返回值 |
reduceRight | (callback(p/上一次回调的返回值,v/当前被处理的元素,i/索引,a/原数组) ,initialValue初始值) | 该方法接收一个函数作为累加器(accumulator),数组中的每个值(从右到左)开始合并,最终为一个值 | 不变 | 最后的返回值 |
Array.from | (类数组对象) | 一个类似数组或可迭代对象中创建一个新的数组实例 | 不变 | 数组实例 |
Array.isArray | (需要检测的元素) | 判断一个元素是否为数组 | 不变 | 布尔值 |
Array.isArray | (元素–可多个) | 创建一个具有可变数量参数的新数组实例 | 不变 | 数组实例 |
fill | (value,开始索引,结束索引) | 将数组中指定区间的所有元素的值,都替换成value | 改变 | 无 |
1、ES5数组方法
push()
可以接受多个参数,并将这些参数放置于数组尾部,返回新数组的长度,原始数组发生改变。
Array.prototype.myPush =function(){
for (var i = 0; i < arguments.length; i++) {
//arguments代表实参的集合
//this 指向的是arr数组
this[this.length] = arguments[i];
}
//由于push 返回值 是一个数组的长度 所以 我们来个return;
return this.length;
};
arr.push(4,5,6);
alert(arr);
//-----结果 [1,2,3,4,5,6];
pop()
不接收参数,从数组尾部删除一个元素,并返回这个删除的元素,原数组发生改变。
Array.prototype.myPop = function( ){
var len=this.length;
var result = this[len-1];
this.length = len - 1;
return result;
}
var a = [1,2,3,4]
console.log(a.myPop( ))//-----结果4;
console.log(a);//-----结果 [1,2,3];
unshift()
接受多个参数并,将这些参数放置于数组头部,返回新数组的长度,原数组发生改变。
Array.prototype.myUnshift=function( ){
var len=arguments.length-1;
this.length=this.length+len;
for(var i=this.length-1;i>=0;i--){
this[i+len]=this[i]
}
for(var j=1;j<arguments.length;j++){
this[j-1]=arguments[j]
}
return this.length
}
var arr=[1,2,5,6];
arr.unshift(10,11)//6
console.log(arr)//[10,11,1,2,5,6];
shift()
不接受参数,从数组的头部删除一个元素,并返回这个删除的元素,原数组发生改变。
Array.prototype.myShift = function(){
var result = this[0]
for(var i=0;i<this.length-1;i++){
this[i] = this[i+1]
}
this.length = this.length-1
return result;
}
var a = [1,2,3,4]
a.myShift()//1
console.log(a)//[2,3,4]
slice()
如果是一个参数,那么该参数表示的索引开始截取,直至数组结束,返回截取的数组,原数组不发生改变。
如果有两个参数,从第一个参数表示的索引开始截取,到第二个参数表示的索引结束,不包括第二个参数对应的索引位上的元素。
Array.prototype.mySlice = function () {
var startIndex = Number(arguments[0]),
endIndex = Number(arguments[1]),
newArr = [];
endIndex =endIndex === undefined ? this.length : Number(endIndex) ? Number(endIndex) : 0;
endIndex =endIndex < 0 ? Math.abs(endIndex) > this.length &&endIndex > -1? 0 :
this.length + Math.ceil(endIndex) :endIndex > this.length ? this.length : Math.floor(endIndex);
startIndex = startIndex ? startIndex < 0 ? Math.abs(startIndex) > this.length || startIndex > -1
? 0 : this.length + Math.ceil(startIndex) : startIndex > this.length ? this.length: Math.floor(startIndex) : 0;
for (var i = startIndex; i <endIndex; i++) {
newArr[newArr.length] = this[i];
}
return newArr;
};
var arr=[1,2,3,4,5];
var a1=arr.mySlice(1,3);
console.log(Array.prototype.slice.call({ 0:'a', 1:'b', length:2 }))// ["a", "b"]
console.log(a1)//[2, 3],
注; slice方法的一个重要应用,是将类似数组的对象转为真正的数组。
Array.prototype.slice.call({ 0:'a', 1:'b', length:2 }) /// ['a', 'b']
Array.prototype.slice.call(document.querySelectorAll("div"));
Array.prototype.slice.call(arguments);
上面代码的参数都不是数组,但是通过call方法,在它们上面调用slice方法,就可以把它们转为真正的数组。
var arr=[1,2,3,4,5,6];
var arr1=arr.slice(1,3);
var arr1=arr.slice( );
//如果没有任何参数就会从头截取到尾部 拷贝
var arr1=arr.slice(1);
//如果第二个参数没有,就会从开始截取到尾部
var arr1=arr.slice(-3,-1);
//如果是负数就会从后向前数,然后再截取
//前小于后将参数转换为正向数值时,前面的必须小于后面
var arr1=arr.slice(-3,5);
//如果第一个参数大于等于数组长度,或者第二个参数小于第一个参数,则返回空数组。
console.log(arr1,arr);
splice()
如果一个参数,那么从该参数表示的索引开始截取,直至数组结束,返回截取的数组,原数组发生改变。
如果有两个参数,从第一个参数表示索引,第二个参数表示的是截取的长度。
如果有三个及以上参数,从第一个参数表示索引,第二个参数表示的是截取的长度,后边的会从截取的位置添加至原数组里。
- splice方法用于删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。
arr.splice(start, count, addElement1, addElement2, ...);
- splice的第一个参数是删除的起始位置(从0开始也包含该元素),第二个参数是被删除的元素个数。如果后面还有更多的参数,则表示这些就是要被插入数组的新元素。
var a = ['a', 'b', 'c', 'd', 'e', 'f'];
a.splice(4, 2) ["e", "f"]
a ["a", "b", "c", "d"]
上面代码从原数组4号位置,删除了两个数组成员。
var a = ['a', 'b', 'c', 'd', 'e', 'f'];
a.splice(4, 2, 1, 2) // ["e", "f"]
a // ["a", "b", "c", "d", 1, 2]
上面代码除了删除成员,还插入了两个新成员。
3. 起始位置如果是负数,就表示从倒数位置开始删除
var a = ['a', 'b', 'c', 'd', 'e', 'f'];
a.splice(-4, 2) ["c", "d"]
上面代码表示,从倒数第四个位置c开始删除两个成员。
4. 添加元素;如果只是单纯地插入元素,splice方法的第二个参数可以设为0。
var a = [1, 1, 1];
a.splice(1, 0, 2) [ ]
a [1, 2, 1, 1]
5.如果只提供第一个参数,等同于将原数组在指定位置拆分成两个数组。
var a = [1, 2, 3, 4];
a.splice(2) [3, 4]
a // //[1, 2]
原理实现:
Array.prototype.mySplice = function () {
var _arr = [],//操作的原数组
len = this.length,//数组长度
startIndex = arguments[0],//第一个参数:起始索引
deleteNum = arguments[1],//第二个参数:删除长度
insertNum = arguments.length - 2,//添加元素数量
leftArr = [],//删除元素左边数组
rightArr = [];//删除元素右边数组
if (startIndex < 0 || deleteNum < 0) {
return _arr;
}
// 删除
for (var i = 0; i < deleteNum; i++) {
_arr[i] = this[startIndex + i]
for (var i = 0; i < len - deleteNum - startIndex; i++) {
this[startIndex + i] = this[startIndex + deleteNum + i]
}
this.length = len - deleteNum
if (insertNum === 0) {
return _arr
}
}
// 添加;替换
for (var i = 0; i < len - deleteNum; i++) {
if (i < startIndex) {
leftArr[leftArr.length] = this[i]
} else {
rightArr[rightArr.length] = this[i]
}
}
rightArr.length = len - startIndex - deleteNum;
for (var i = 0; i < insertNum; i++) {
leftArr[startIndex + i] = arguments[i + 2];
}
for (var i = 0; i < len - deleteNum + insertNum; i++) {
if (i < startIndex + insertNum) {
this[i] = leftArr[i]
} else {
this[i] = rightArr[i - startIndex - insertNum]
}
}
return _arr;
}
var a = ['a', 'b', 'c', 'd', 'e', 'f',undefined];
a.splice(4, 2)
// var a = ['a', 'b', 'c', 'd', 'e', 'f'];
// a.splice(4, 2, 1, 2)
// var a = ['a', 'b', 'c', 'd', 'e', 'f'];
// a.splice(-4, 2)
// var a = [1, 1, 1];
// a.splice(1, 0, 2);
// var a = [1, 2, 3, 4];
// a.splice(2)
console.log(a)
reverse()
数组翻转参数无意义;改变数组;并返回操作后的原数组。
Array.prototype.myReverse = function( ){
var arr = this;
var len=parseInt(arr.length/2)
for(var i=0;i<len;i++){
var temp=arr[arr.length-1-i]
arr[arr.length-1-i]=arr[i];
arr[i]=temp
}
return arr//改变数组
}
var arr=[1,2,4,5,6,7,7,4,3,5]
arr.myReverse( )
console.log(arr)//[5, 3, 4, 7, 7, 6, 5, 4, 2, 1]
sort()
对数组的元素做原地的排序,并返回这个数组。sort可能不稳定,默认按照字符串的unicode码位点排序。改变数组;并返回操作后的原数组。
var arr = [2,11,50,7,9];
console.log(arr.sort());//按照字符串按位比较方式来判断大小的
arr.sort(function(a,b){
return a - b;//从小到大
return b-a;//从大到小
})
console.log(arr);
[10111, 1101, 111].sort(function (a, b) {return a - b;})
// [111, 1101, 10111]
[4, 3, 2, 1].sort( ) // [1, 2, 3, 4]
[11, 101].sort( ) ///[101, 11]
[
{ name:"张三", age:30 },
{ name:"李四", age:24 },
{ name:"王五", age:28 }]
.sort(function (o1, o2) {
return o1.age - o2.age;})
// [
// { name:"李四", age:24 },
// { name:"王五", age:28 },
// { name:"张三", age:30 }]
原理实现:
Array.prototype.mySort = function(fn){
if(Object.prototype.toString.call(fn)==='[object Function]'){
//如果传进来参数的是函数
for(var i = 0;i<this.length-1;i++){
//遍历数组,将前后两项作为实参传给fn
if(fn.call(this,this[i],this[i+1])>0){
//如果fn执行之后的返回值大于0.就调用swap方法交换位置
var a = this[i],b=this[i+1];
this[i] = swap(a,b).a;
this[i+1] = swap(a,b).b;
//交换之后,如果当前项不是第一项,则当前项(索引为i的项)继续跟前面的项进行比较
if(i>0){
for(var j = i-1;j>=0;j--){
if(fn.call(this,this[j],this[j+1])>0){
var a = this[j],b=this[j+1];
this[j] = swap(a,b).a;
this[j+1] = swap(a,b).b;
}
}
}
}
}
}else{
//如果不是函数,则按正常排序
//遍历数组,将前后两项进行比较
for(var i = 0;i<this.length-1;i++){
var cur = this[i];//当前项
var next = this[i+1];//下一项
if(comASCII(cur,next)){
//当返回true的时候交换,并且交换完成之后,当前项继续往前比较
this[i] = swap(cur,next).a;
this[i+1] = swap(cur,next).b;
//当前项继续向前比较
if(i>0){
for(var k = i-1;k>=0;k--){
var cur = this[k];
var next = this[k+1];
if(comASCII(cur,next)){
this[k] = swap(cur,next).a;
this[k+1] = swap(cur,next).b;
}
}
}
}
}
}
//封装一个交换位置的函数
function swap(a,b){
return {
a:b,
b:a
}
}
//如果不传参的情况下比较ASCII码
function comASCII(cur,next){
//全部转换为字符串、逐项比较ASCII码
cur = cur.toString();
next = next.toString();
//取长度最大值
var len = cur.length>next.length?next.length:cur.length;
//当前后两项都不是不是{}类型的数据时,进行比较
if(cur!=='[object Object]'&&next!=='[object Object]'){
for(var j = 0;j<len;j++){
if(!isNaN(cur.charCodeAt(j))&&!isNaN(next.charCodeAt(j))){
//如果二者的ASCII码都是有效数字
if(cur.charCodeAt(j)>next.charCodeAt(j)){
//如果前一项比后一项当前的ASCII码大,则返回true,交换位置
return true;
}else if(cur.charCodeAt(j)==next.charCodeAt(j)){
//如果相等直接进入下一轮循环
continue;
}else{
//前项比后项小,直接返回false
return false;
}
}
}
if(!isNaN(cur.charCodeAt(len))&&isNaN(next.charCodeAt(len))&&(cur.charCodeAt(len-1)==next.charCodeAt(len-1))){
//比较完之后,如果前一项ASCII还是有效数字,说明前项比后项大,交换
return true;
}
}
//如果上述条件不满足,则不交换
return false;
}
//返回当前数组
return this;
};
说到排序就不得不说三种经典的排序方式:
1. 冒泡排序
//原理:数组中有n个数,比较相邻的两个数,如果后面的数小于前面的数,则两者交换。
//一轮完成后,此时最大的数据已经在最后,此时进行第二轮,确定倒数第二个数,依次几轮就可完成:
//1、从后向前循环
//2、内部从前向后循环到外层变量
//3、判断前面的值是否大于后面的值,交换
Array.prototype.Mpsort=function(){
var arr=this;
var len=arr.length;
while(len>0){
for(var i=0;i<len;i++){
if(arr[i]>arr[i+1]){
var temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
len--;
}
}
var arr=[1,2,4,6,3,2,6,8]
arr.Mpsort();
console.log(arr);
2. 快速排序
//原理:取数组中间位置的数据,跟所有数据比较,比该数小的放一新数组,大的放一新数组,使用递归,拼接数据,最后得到想要的数组
//重新赋值给元素替换
Array.prototype.quickSort = function ( ) {
var arr=this
if (arr.length <= 1) { return arr; }
var item = arr.splice(parseInt(arr.length / 2), 1)[0];
// var item = arr.splice(Math.floor(arr.length / 2), 1)[0];
var leftArr = [];
var rightArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] < item) {
leftArr.push(arr[i]);
} else {
rightArr.push(arr[i]);
}
}
return leftArr.quickSort().concat([item], rightArr.quickSort());
};
var arr = [1, 2, 34, 2, 1, 3, 2, 8]
arr=arr.quickSort();
console.log(arr)
3. 选择排序
//选择排序;
//先找出最小或者最大的索引值,然后用当前的下标的元素与这个最小的元素比较
Array.prototype.mySort=function(){
var minIndex;
var arr=this;
for(var i=0;i<arr.length;i++){
minIndex=i;
for(var j=i+1;j<arr.length;j++){
minIndex=arr[minIndex]<arr[j]?minIndex:j;
}
var temp=arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=temp;
}
}
var arr=[1,2,4,5,6,32,2,2];
arr.mySort();
console.log(arr)
join()
将数组中元素以参数来进行拼接;不改变原数组。
var arr = [1,2,3,4];//"1234"
var str = arr.join("-----");
console.log(str,arr)
原理实现:
Array.prototype.myJoin=function(separator){
var str = "";
if (!this|| !(this.constructor===Array)) return str;
if (separator === undefined) separator = ",";
separator = String(separator);
for (var i = 0; i < this.length; i++) {
i===this.length-1?str += this[i]:str += this[i] + separator
}
return str;
}
var arr=[1,2,3,4]
var item=arr.myJoin("&")
console.log(arr);
console.log(item)
concat()
合并数组,将参数放到原数组里,如果参数是一个数组,把数组中的元素提出来,放到原数组中。不改变原数组。
Array.prototype.myConcat = function() {
var arr = JSON.parse(JSON.stringify(this));
// 这里用JSON可以深度拷贝数组
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
for ( var j = 0; j < arg.length; j++ ) {
arr.push(arg[j]);
}
};
return arr;
}
var arr1 = [1,2,3], arr2 = ['a','b','c'];
console.log("arr1.myConcat(arr2)":arr1.myConcat(arr2));
console.log("arr1":arr1);
console.log("arr2":arr2);
toString( )
使数组变成字符串,用’,’连接。若数组的值存在数组,会便遍历拼接在字符串里;对象,会变成[object Object];undefined则什么都不连接,返回最后转化的字符串;不会改变原数组。
toLocalString( )
使数组变成字符串,用’,’连接。数组内的元素会调用自己的toLocalString方法;返回最后转化的字符串;不会改变原数组。
for
遍历数组;(不用for in遍历)
var arr = ["a","b","c","d"];
for(var i = 0; i < arr.length; i++){
console.log(arr[i]);
}
2、ES6新增数组方法
敲黑板!!重点来了!
indexOf()
找出数组中是否有给定值的元素,并返回找到的第一个元素的索引值;如果没有则返回-1。
// 原理:indexOf方法,在数组循环过程中会和传入的参数比对,
// 如果是比对成功,那么终止循环,返回对比成功的下标,
Array.prototype.myIndexOf = function(){
var startIndex=arguments[1];
var arr = this;
var index = -1;
for (var i = 0; i < arr.length; i++) {
if (arr[i] === arguments[0]&&(startIndex===undefined||startIndex!==undefined&&i>=startIndex)) {
index = i;
break;
}
}
return index;
}
var a = [1, 2, 3];
var b = a.myIndexOf(2);
console.log(a);
console.log(b); // 结果为1
lastIndexOf ()
找出数组中是否有给定值的元素,并返回找到的最后一个元素的索引值;如果没有则返回-1。
Array.prototype.lastIndexOf = function (value) {
var startIndex=arguments[1];
var arr = this;
var index = -1;
for (var i = arr.length; i--;) {
if (arr[i] === arguments[0]&&(startIndex===undefined||startIndex!==undefined&&i>=startIndex)) {
index = i;
return index
}
}
return index;
}
var a = [1, 2, 3, 1];
var b = a.lastIndexOf(1);
console.log(b)
forEach()
如果不接受参数,遍历数组中每一个元素。
如果接受参数,分别为:item, index, array, (用不到时可以不写);item 表示每次迭代的元素;index 表示每次迭代元素的下标;array 表示原数组。
var a = [1,2,3];
a.forEach(function(value,key,arr){
console.log(value)
// 结果依次为1,2,3
console.log(key)
// 结尾依次为0,1,2
console.log(arr)
// 三次结果都为[1,2,3],该参数貌似没什么用
})
//项目应用
this.datalist.forEach((item, index) => {
if (item._id === id) {
this.once=item
}
});
原理实现:
Array.prototype.myForEach = function (callback) {
if (typeof callback !== 'function') {
throw new Error(callback + 'is not function');
}
var arr = this;
var _this = arguments[1] || window;
for (var i = 0; i < arr.length; i++) {
if (this[i] === undefined) continue;
// callback.apply(_this,[arr[i], i, arr])
callback.call(_this, arr[i], i, arr)
}
}
var arr1 = [1, 2, 3];
var newArr = [ ]
// 桥接模式;自身方法不做任何处理;让回调函数去做处理
arr1.myForEach(function (value, key, arr) {
console.log(value, key, arr)
this.push(value *key)
},newArr)
console.log(newArr)
map()
返回一个新数组,新数组是原数组的映射;不改变原数组的值;新数组的元素值是每次函数return的返回值;若不写return,接收的新数组的元素值将全为空。
var arr = [20,13,11,8,0,11];
var brr = arr.map(function(item)){
//将数组的每个元素都将增加到原来的1.2倍
return item*1.2;
// 此时brr为a数组每个元素的1.2倍
//若return 1,则新数组的每个元素值均为1
return 1;
}
//项目应用
this.datalist.map((item, index) => {
if (item._id === id) {
item=this.once
}
});
原理实现:
Array.prototype.myMap = function (callback, bindingArr) {
if (typeof callback !== 'function') {
throw new Error(callback + 'is not function');
}
var newArr = [];
var arr = this;
var _this = arguments[1] || window;
for (var i = 0; i < arr.length; i++) {
newArr.push(callback.apply(_this,[arr[i], i, arr]))
// newArr.push(callback.call(_this, arr[i], i, arr))
}
return newArr;
}
var arr = [1, 2, 3];
var bindingArr = [1, 2];
var b = arr.myMap(function (value, key, arr) {
// console.log(value, key, arr)
// return value + 1;
return this.push(value+1)
}, bindingArr)
// console.log(arr);
// console.log(b);
console.log(bindingArr)
filter()
过滤元素,返回一个新数组;新的数组由每次函数返回值为true对应的元素组成;原数组不受影响。
var arr = [20,13,11,8,0,11];
var brr =arr.filter(function(item)){
//返回值为奇数的元素
return item%2;
}
//项目应用
let result=this.originlist.filter((item)=>{
let reg=RegExp(this.keyword,"i")
return reg.test(item.companyName)
})
let startIndex=(this.pageno-1)*this.pagesize
let endIndex=startIndex+this.pagesize
return result.slice(startIndex,endIndex)
}
原理实现:
Array.prototype.myFilter = function (callback) {
if (typeof callback !== 'function') {
throw new Error(callback + 'is not function');
}
var arr = this;
var _arr = [ ];
for (var i = 0; i < arr.length; i++) {
var fn = callback(arr[i], i, this);
if (fn) {
_arr.push(arr[i]);
}
}
return _arr;
}
var a = [1, 2, 3];
var b = a.myFilter(function (value, key, arr) {
console.log(value, key, arr)
return value<3;
})
console.log(a);
console.log(b);
some()
return返回的值只要有一项为true,最终的返回值就为true,不会继续遍历后边的元素;
若没有一项满足返回值为true的,就返回false;原数组不受影响;
var arr = [20,13,11,8,0,11];
var brr = arr.some(function(item){
return item>10;
})
alert(brr); //true
原理实现:
Array.prototype.mySome = function (callback, countInit) {
var arr = this;
var bool = false;
for (var i = 0; i < arr.length; i++) {
var cbValue = callback(arr[i], i, this);
if (cbValue) {
bool = true;
return bool
}
}
return bool;
}
var arr= [1, 2, 3];
var b = arr.mySome(function (value, key, arr) {
console.log(value, key, arr);
return arr.indexOf(4);
})
console.log(arr);
console.log(b);
every()
对数组的每一项执行给定的函数,假如该函数每一项都返回true,最后结果才为true;
只要有一项返回值为false,最后结果就是false。且后边的元素都不会再继续执行函数;
原数组不受影响;
var a = [1,2,3];
var b = a.every(function(value,key,arry){
console.log(value); // 结果依次为1,2
console.log(key); // 结果依次为0,1
console.log(arry); // 两次次结果都为[1,2,3]
return value===2;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为false
原理实现:
Array.prototype.myEvery = function (callback, bindingArr) {
if (typeof callback !== 'function') {
throw new Error(callback + 'is not function');
}
var _this = arguments[1] || window;
var arr = this;
var bool = true;
for (var i = 0; i < arr.length; i++) {
var cbValue = callback.call(_this, arr[i], i, arr);
if (cbValue) {
bool = false;
return bool
}
}
return bool;
}
var a = [1, 2, 3];
var b = a.myEvery(function (value, key, arr) {
console.log(value, key, arr);
return value===4;
})
console.log(a);
console.log(b);
reduce()
返回值是最后一次函数调用的返回值;
不写return时,默认返回undefined;
运行机制:一开始,prev代表数组第一个元素,next指向数组第二个元素 ;函数有个返回值,会作为下次的prev值;当给方法第二个参数值时,prev从传的第二个参数值开始,next从第一个元素值开始
用途:
过滤效果:return item.id=1006?item:value;
归并求和:return item.select?value+item.total:value;
var arr = [1,4,5,7,8,10];
var res = arr.reduce(function(prev,next){
console.log(prev+"---"+next);
return 4;
})
console.log(res);
//reduce()还可以有第二个参数
var arr = [1,4,5,7,8,10];
var res = arr.reduce(function(prev,next){
console.log(prev+"---"+next);
return prev+next;
},100) //prev从传的第二个参数值100开始,next从第一个元素值开始
console.log(res);
原理实现:
Array.prototype.myReduce = function (callback, initValue) {
if (typeof callback !== 'function') {
throw new Error(callback + 'is not function');
}
var start=0;
if(initValue===undefined){
initValue=arr[0];
start++;
}
var arr = this;
for (var i = start; i < arr.length; i++) {
var cbValue = callback(initValue, arr[i], i, this);
initValue = cbValue;
}
return initValue;
}
var a = [1, 2, 3];
var b = a.myReduce(function (initValue, value, key, arr) {
// console.log(initValue, value, key, arr);
return initValue + value;
}, 0);
console.log(a);
console.log(b)
代码解读:reduce的不同之处在于累加,和其他几个内置方法不同的地方,它的第二个参数不是this对象,而是初始累加值(如果不设置的话数组会乱掉),而且回调函数的的个数也不同,比其他的多了一个,而且还在在开始的多加了一个参数,第一个参数记录的是上一次循环的累加值;
reduceRight( )
该方法接收一个函数作为累加器(accumulator),数组中的每个值(从右到左)开始合并,最终为一个值;与reduce原理类似;不会改变原数组并迭代到最后的返回值
3、ES7新增数组方法
keys( )
返回一个新的Array迭代器,它包含数组中每个索引的键;不会改变数组。
let arr=[1,2,234,'sdf',-2];
for(let a of arr.keys( )){
console.log(a)
}
//结果:0,1,2,3,4
//此处keys,对数组索引进行遍历
values( )
返回一个新的Array迭代器,它包含数组中每个值的键;该方法不会改变数组。
let arr=[1,2,234,'sdf',-2];
for(let a of arr.values()){
console.log(a) }
//结果:1,2,234,sdf,-2
//values, 遍历了数组arr的值
entries( )
返回一个新的Array迭代器,它包含数组中每个键值对[index,item];该方法不会改变数组。
for(let a of arr.entries()){
console.log(a)
}
//结果:[0,w],[1,b]
for(let [i,v] of arr.entries()){
console.log(i,v)
}
//结果:0 w,1 b
//entries,对数组键值对的遍历。
includes( )
includes函数与string的includes一样,接收2参数,查询的项以及查询起始位置。用来判断当前数组是否包含某指定的值;返回一个布尔值;该方法不会改变数组
arr.includes(20);// 结果:false,返回布尔值
arr.includes(2,3)//结果:false,返回布尔值
Array.from( )
在一个类似数组或可迭代对象中创建一个新的数组实例并返回该数组实例。
Array.from({'0':'w','1':'b',length:2})
//["w", "b"],返回数组的长度取决于对象中的length,故此项必须有!
Array.from({'0':'w','1':'b',length:4})
//["w", "b", undefined, undefined],数组后2项没有属性去赋值,故undefined
Array.from({'0':'w','1':'b',length:1})
//["w"],length小于key的数目,按序添加数组
let ps=document.getElementsByTagName('p');
Array.from(ps)
//返回p元素数组
Array.from('wbiokr')
//["w", "b", "i", "o", "k", "r"]
Array.from([1,2,3],function(x){
return x+1})
//[2, 3, 4],第二个参数为回调函数
Array.isArray( )
用于判断一个元素是否为数组返回布尔值还可以用于创建一个具有可变数量参数的新数组实例;并返回该数组实例
fill( )将数组中指定区间的所有元素的值,都替换成第一个参数值;当第三个参数大于数组长度时候,以最后一位为结束位置。该方法会改变数组;没有返回值。
let arr=['w','b'];
arr.fill('i')
//结果:['i','i'],改变原数组
arr.fill('o',1)
//结果:['i','o']改变原数组,第二个参数表示填充起始位置
new Array(3).fill('k').fill('r',1,2)
//结果:['k','r','k'],第三个数组表示填充的结束位置
copyWithin( )
用于在数组内的替换操作,即替换元素和被替换元素都是数组内的元素;copyWithin方法接收三个参数,被替换数据的开始处、替换块的开始处、替换块的结束处(不包括);copyWithin(s,m,n)。该方法会改变数组,并返回改变后的数组。
["w", "i", "r"].copyWithin(0)//此时数组不变
["w", "i", "r"].copyWithin(1)
//["w", "w", "i"],数组从位置1开始被原数组覆盖,只有1之前的项0保持不变
["w", "i", "r","b"].copyWithin(1,2)
//["w", "r", "b", "b"],索引2到最后的r,b两项分别替换到原数组1开始的各项,当数量不够,变终止
["w", "i", "r",'b'].copyWithin(1,2,3)
//["w", "r", "r", "b"],强第1项的i替换为第2项的r
find( )
返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。该方法不改变原数组。
let arr=[1,2,234,'sdf',-2];
arr.find(function(x){
return x<=2;
})//结果:1,返回第一个符合条件的x值
arr.find(function(x,i,arr){
if(x<2){console.log(x,i,arr)}
})
//结果:1 0 [1, 2, 234, "sdf", -2],-2 4 [1, 2, 234, "sdf", -2]
findIndex( )
返回数组中满足提供的测试函数的第一个元素的值的索引。否则返回 undefined。该方法不改变原数组。findIndex和find差不多,不过默认返回的是索引。
let arr=[1,2,234,'sdf',-2];
arr.findIndex(function(x){
return x<=2;
})
//结果:0,返回第一个符合条件的x值的索引
arr.findIndex(function(x,i,arr){
if(x<2){console.log(x,i,arr)}
})
//结果:1 0 [1, 2, 234, "sdf", -2],-2 4 [1, 2, 234, "sdf", -2]