){
for(let i = 0; i < arguments.length; i++){
this[this.length] = arguments[i]
return this.length;
不接收参数,删除数组中最后一个元素,返回被删除元素
let arr = [1,2,3,4]
let res = arr.pop()
console.log(res,arr)
使用length减少数组长度即可
Array.prototype.myPop = function(){
if(this.length == 0) return;
let last = this[this.length-1];
this.length--;
return last;
unshift(val)
添加val到数组开头,返回被修改的数组长度。
let arr = [1,2,3,4]
let res = arr.unshift(1,2)
console.log(res,arr)
把arguments与数组的数据都放到一个新数组里面,然后再覆写到原数组
Array.prototype.myUnshift = function(){
let newArr = [...arguments,...this];
let len = newArr.length
for(let i = 0; i < len; i++){
this[i] = newArr[i]
return this.length;
shift
删除数组的第一个元素,返回被删除元素
let arr = [1,2,3,4]
let res = arr.shift()
console.log(res,arr)
使用值覆盖的原理
Array.prototype.myShift = function(){
let first = this[0];
for(let i = 1; i < this.length; i++){
this[i-1] = this[i]
this.length? this.length-- : 'undefined'
return first;
reverse
反转数组,返回反转后的数组
let arr = [1,2,3,4]
let res = arr.reverse();
console.log(res,arr)
---无法进行深反转---
arr = [1,[2,3],[4,5]];
res = arr.reverse();
console.log(res,arr);
首尾互换。
Array.prototype.myReverse = function(){
var count = Math.floor(this.length/2);
for(let i = 0; i< this.length; i++){
if(i >= count) return this;
let temp = this[i];
this[i] = this[this.length-1-i];
this[this.length -1- i] = temp
splice(index,count,val)
从索引为index处删除count个元素,插入value,返回被删除的数据组成的新数组
let arr = [1,2,3,4];
let res = arr.splice(1,2,5)
console.log(res,arr)
---其他操作,负数(= length+负数),count不存在默认为数组的长度---
arr = [1,2,3,4];
res = arr.splice(-2);
console.log(res,arr);
---插入操作---
arr = [1,2,3,4];
res = arr.splice(-2,1,'A','B')
console.log(res,arr); [3] [1,2,'A','B',4]
Array.prototype.mySplice = function(index,count,...addElm){
let len = this.length;
let addCount = addElm.length;
index = computedIndex(index,len);
count = computedCount(index,count,len)
console.log(index,count)
let delArr = new Array(count).fill(null);
sliceDelElm.call(this,index,count,delArr);
console.log(delArr)
console.log(addElm)
removeArr.call(this,count,addCount);
for(let i = 0; i < addCount; i++){
this[index+i] = addElm[i]
this.length = this.length - count+ addCount;
return delArr;
function computedIndex(index,len){
if(index < 0) return index + len > 0 ? index + len : 0;
return index - len > 0 ? len : index;
function computedCount(index,count,len){
if(typeof count == 'undefined') return len - index
if(count < 0) return 0;
if(count > len - index) return len - index;
return count;
function sliceDelElm(index,count,delArr){
for(let i = 0; i <count; i++ ){
delArr[i] = this[index+i];
function removeArr(count,addCount){
if(count < addCount){
for(let i = this.length-1; i >= index + count; i--){
let fromIndex = i;
let toIndex = i + addCount - count;
this[toIndex] = this[fromIndex];
else if(count > addCount){
for (let i = index + count; i < this.length; i++) {
let fromIndex = i;
let toIndex = i - count + addCount;
this[toIndex] = this[fromIndex];
for(let i = this.length - 1; i >= this.length - count + addCount; i-- ){
delete this[i]
else{
return;
sort (fn)
该方法默认按照数组元素ASCII 字符顺序排列,返回对原数组的引用。请注意,数组在原数组上进行排序,不生成副本。
let arr = [1,5,4,2,3,6];
let res = arr.sort();
console.log(res,arr)
Array.prototype.mySort
= function(fn){
不改变原数组
slice(index,len)
拷贝数组元素,拷贝区间为前闭后开[start,end)
let arr = [1,2,3,4];
let res = arr.slice(1,3);
console.log(res,arr)
console.log(arr.slice(1));
console.log(arr.slice(-1));
console.log(arr.slice(-1,1))
console.log(arr.slice(1,-1))
console.log(arr.slice(-1,-2));
console.log(arr.slice(-2,-1));
Array.prototype.mySlice = function(inStart,exEnd){
if(inStart == 'undefined' || exEnd == 'undefined') return;
let len = this.length;
inStart = computedInStart(inStart,len);
exEnd = computedExEnd(inStart,exEnd,len);
let newArr = [];
for(let i = inStart; i < exEnd; i++){
newArr[newArr.length] = this[i]
return newArr;
function computedInStart(inStart,len){
if(inStart < 0){
return inStart + len > 0 ? inStart + len : 0;
return inStart > len ? len : inStart;
function computedExEnd(inStart,exEnd,len){
if(typeof exEnd == 'undefined') return len;
if(exEnd < 0) return exEnd + len > 0 ? exEnd + len : 0;
if(exEnd > len - inStart) return exEnd%len;
return exEnd;
concat(arr)
连接合并多个数组,返回新数组
let arr = [1,2,3,4];
let arr1 = [5,6,7,8];
let res = arr.concat(arr1);
console.log(res,arr)
---支持同时合并多个数组---
let arr2 = [9,10];
let res = arr.result(arr1,arr2);
console.log(res,arr);
--- concat不支持深度合并----
arr.concat([5,6],[[7,8],4])
Array.prototype.myConcat = function(){
let result = JSON.parse(JSON.stringify(this));
for(let i = 0; i < arguments.length; i++){
let argu = arguments[i];
if(Object.prototype.toString.call(argu) === '[object Array]'){
for(let j = 0; j < argu.length; j++){
result.push(argu[j])
}else{
result.push(argu);
return result
join(val)
将数组用value连接为字符串,返回连接的字符串
let arr = [1,2,3,4];
let res = arr.myJoin('.');
console.log(res,arr)
Array.prototype.join = function(char){
let result = this[0] || '';
let length = this.length;
for(let i = 1; i < length; i++){
result += char + this[i];
return result;
split()
数组迭代方法(不改变原数组)
先声明两个数据,后面的操作都以这两个数据为基础
let arr = [
name: '张三丰',
age: '18',
sex: 'male',
name: '张三',
age: '34',
sex: 'male'
name: '爱丽丝',
age: '16',
sex: 'female'
let obj = {name:'HSM'}
forEach
该方法接收两个参数,第一个参数是一个函数,然后反复的调用该函数,调用的次数取决了数组的长度,并且会给调用的函数传递三个参数,ele,index,self(数组本身)。第二个参数是一个对象,表示将第一个参数(函数)的this指向指向该obj,否则就是默认指向window
function deal(item,index,self){
console.log(item,index,self,this)
arr.myForEach(deal,obj)
Array.prototype.myForEach = function(func){
let len = this.length;
let _this = arguments[1] || window;
for(let i = 0; i < len; i++){
func.apply(_this,[this[i],i,this])
下面所有的方法都是基于forEach方法进行二次改进的
filter
filter方法基于forEach。
二次改进的地方在于调用该方法最终会返回一个新数组,return true的函数内容(item)会被放入到新数组中,起到过滤的作用。
function filterDeal(item,index,self){
console.log(this)
if(item.sex =='male') return true
var newArr = arr.filter(filterDeal,obj);
console.log(newArr)
Array.prototype.myFilter = function(func,obj){
let _arr = [];
let len = this.length;
let _this = obj || window
for(let i = 0; i < len; i++){
func.apply(_this,[this[i],i,this]) && _arr.push(this[i])
return _arr;
map(引用类型会改变原数据)
返回一个新数组,数组中的元素为原始数组元素调用函数处理后返回 的值。
当数组中元素是值类型,map不会改变原数组;当是引用类型,则可以改变原数组。因为基本类型返回的是值到新数组中,引用类型改变了内部的值
例子:引用类型值会被修改
function MapDeal(item,index,self){
console.log(this)
item.age = +item.age + 10;
return item
var newArr = arr.map(MapDeal,obj);
console.log(newArr)
console.log(arr)
基本类型原数组不会被修改
var arr2 = [1,2,3]
var newArr = arr2.map(function(item,index,self){
return item*2
console.log(newArr);
console.log(arr2);
也可以单独抽离出需要返回的内容
function MapDeal3(item,index,self){
console.log(this)
return item.age
var newArr = arr.map(MapDeal3,obj);
console.log('newArr:',newArr)
console.log('arr:',arr)
Array.prototype.myMap = function(func,obj){
let arr = [];
let len = this.length;
let _this = arguments[i] || window;
for(let i = 0; i < len; i++){
arr.push(func.apply(_this,[this[i],i,this]))
return arr;
可以理解为promise中的race,该函数只返回一个Boolean值
判断数组中的元素是否都符合条件,有一个符合条件就返回true,全不符合条件才返回false
arr.some(function(item,index,self){
console.log(this)
if(item.age > 20){
return true
return false;
Array.prototype.mySome = function (func, obj) {
let flag = false;
let len = this.length;
let _this = arguments[1] || window;
for (let i = 0; i < len; i++) {
if (func.apply(_this, [this[i], i, this]) == true) {
flag = true;
break;
return flag
every
可以理解为Promise中的all ,该函数只返回一个Boolean值。
判断数组中的元素是否都符合条件,全符合返回true,有一个不符合就返回false
arr.every(function(item,index,self){
console.log(this)
if(item.age > 20){
return true
return false;
Array.prototype.myEvery = function (func, obj) {
let flag = true;
let len = this.length;
let _this = arguments[1] || window;
for (let i = 0; i < len; i++) {
if (func.apply(_this, [this[i], i, this]) == false) {
flag = false;
break;
return flag
reduce
从左向右进行遍历,这个方法有点像接力
原始的该方法只接收两个参数,一个是函数,一个是初始值,该函数也接收4个参数,prevValue,item,index,self,其中的prevValue默认就是initValue的值,函数每一次return的值,都会赋予prevValue,如果函数没有return ,就默认undefined,最后一次的return 会返回给外部函数接收
function reduceDeal(prev,item,index,self){
console.log(prev,item.index,self)
arr.reduce(reduceDeal,3)
案例:将cookie字符串形式转化成对象形式;
var str = "PSTM=1547202501;BIDUPSID=51A74B310E1C99BD28A9FA40AB749FD6;MSA_WH=375_667;BAIDUID=0D8F8152E381149:FG=1;BD_UPN=12314753;H_WISE_SIDS=140797_142277_110085;BDORZ=B490B5EBF6F3CD402E515D22BCDA1598;BD_HOME=1;H_PS_PSSID=31782_31464_31322_30824;delPer=0;BD_CK_SAM=1;PSINO=7;H_PS_645EC=bHv5XGOaNHro5ko"
function parseCookidStr(str){
var obj1 = {};
var cookieArr = str.split(/[:;]/);
return cookieArr.reduce(function(prev,cur,index,self){
var newArr = cur.split('=')
prev[newArr[0]] = newArr[1];
return prev
},obj1)
var cookieObj = parseCookidStr(str);
console.log('最终结果是:'cookieObj)
Array.prototype.myReduce = function(func,initialValue){
let len = this.length;
let _this = arguments[2] || window;
let nextValue = initialValue
for(let i = 0; i < len; i++){
nextValue = func.apply(_this,[nextValue,this[i],i,this])
return nextValue
reduceRight(func,initValue)
从右向左进行遍历
var str = "PSTM=1547202501;BIDUPSID=51A74B310E1C99BD28A9FA40AB749FD6;MSA_WH=375_667;BAIDUID=0D8F8152E381149:FG=1;BD_UPN=12314753;H_WISE_SIDS=140797_142277_110085;BDORZ=B490B5EBF6F3CD402E515D22BCDA1598;BD_HOME=1;H_PS_PSSID=31782_31464_31322_30824;delPer=0;BD_CK_SAM=1;PSINO=7;H_PS_645EC=bHv5XGOaNHro5ko"
function parseCookidStr(str){
var obj1 = {};
var cookieArr = str.split(/[:;]/);
return cookieArr.reduceRight(function(prev,cur,index,self){
console.log(prev,cur)
var newArr = cur.split('=')
prev[newArr[0]] = newArr[1];
return prev
},obj1)
var cookieObj = parseCookidStr(str);
console.log('最终结果是:',cookieObj)
Array.prototype.myReduceRight = function(func,initialValue){
let len = this.length;
let _this = arguments[2] || window;
let nextValue = initialValue
for(let i = len-1; i >= 0; i--){
nextValue = func.apply(_this,[nextValue,this[i],i,this])
return nextValue
ES6