(七)引用类型详解 - Array类型

1. 检测数组

对于全局作用域而言,前面讲过instanceof操作符。

 if(value instanceof Array){
   //对数组执行某些操作
   }

如果页面存在多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的Array构造函数。(instanceof 就是判断一个实例是否属于某种类型)那么上面的方法就不能用了。es5为此新增了Array.isArray()方法。

 if(Array.isArray(value)){
   //对数组执行某些操作
   }

2. array的栈方法;

栈是一种\color{#34a853}{后进先出}\的数据结构,最新添加的项,最早被移除。(像子弹夹一样,最后放进去的子弹,最先出。)
es为数组专门提供了push()pop()方法,实现类似于栈的行为。

push()接受任意数量的参数,把他们逐个添加到素组尾端,返回数组的长度。

var colors = new Array();
var count = colors.push('red','blue');
  console.log(count) // 2

pop()从数组中移除最后一项,减少数组的length值,并返回最后一项。

var colors = ['red','blue','green'];
var item  = colors.pop();
 console.log(item) // 'green'
 console.log(colors.length) // 2

3. array的队列方法

shift(),移除数组的第一项,并返回该项。同时数组的长度减1.

var  colors = ['red','blue','green'];
var item  =  colors.shift();
  console.log(item)  //'red'

unshift(),则相反,它能在数组的前端添加任意项并返回新数组的长度。

var  colors = ['red','blue','green'];
var   count  =  colors.unshift(‘black’,'white');
  console.log(count)  // 5

4.重排序方法

数组中已存在两个可以直接用来重排序的方法:reverse()sort();
reverse()反转数组的排序

var values = [1,2,3,4,5];
 values.reverse();
  console.log(values); //[5,4,3,2,1]

  • 在默认(不传参)情况下sort()按升序排列数组项——最小的值在最前面,sort()方法会调用每一项的toString()转型方法,比较得到的字符串。即便是数字也是调用字符比较。
var values = [15,5,0,10,20];
 values.sort();
  console.log(values); // [20,15,10,5,0]
var arr = ['arr','blue',2,4,3,2,7];
arr.sort();
console.log(arr) // [2, 2, 3, 4, 7, "arr", "blue"]
  • 默认的排序方案在很多情况下不是最佳方案,因此sort()方法也可以接收一个比较函数,以便我们制定数组的排序。
function compare1(value1,value2){
      if(value1<value2){
          return -1;
        } else if(value1>value2){
          return 1;
        } else{
          return 0;
      }
};
function compare2(value1,value2){
      if(value1<value2){
          return 1;
        } else if(value1>value2){
          return -1;
        } else{
          return 0;
      }
};
var arr = [0,1,5,10,15,20];
arr.sort(compare1);
// [0, 1, 5, 10, 15, 20]
arr.sort(compare2)
 // [20, 15, 10, 5, 1, 0]

上面只是反转数组原来的顺序,虽然说sort()方法都能做到,但是reverse()更快一些。

5.Array的操作方法

  • concat()
    它会创建一个副本,然后给接收到的参数添加到这个副本的尾部,返回新构建的数组,
var arr  =  [1,2,3,4];
var arr1 = [5,6,7];
var arr2 = arr.concat(arr1);
console.log(arr2)
//[1, 2, 3, 4, 5, 6, 7]

传递的参数不是数组的情况,会将参数添加到结果数组的尾部。

var arr  =  [1,2,3,4];
var arr1 = [5,6,7];
var arr2 = arr.concat(arr1,8,9,0);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

不传参的情况下,浅层拷贝。
这些只深复制了基本类型数据类型,不是真正意义的深复制,当然,如果要复制的数组都是简单数据类型,那就大胆用吧。

var arr = [1,2,3,4]
arr2 = arr.concat()
/// [1, 2, 3, 4]
arr2[1] = 3;
console.log(arr)
///[1, 2, 3, 4]

  • slice()
    它基于当前数组中的一个或多个项创建并返回一个新的数组,这个方法不影响原数组。
    objectArray.slice(star,end);
    star - 起始位置
    end - 结束位置
    一个参数的情况下,则默认为源数组的末尾。
var arr = [1, 2, 3, 4, 5, 6];
arr.slice(2)
[3,4,5,6]

负数的情况下,则用数组的长度加上负数来确定响应起始位置。

var arr = [1, 2, 3, 4, 5, 6];
arr.slice(-2)
//[5,6]
arr.slice[-2,-1]
//[5]

当传入的end小于star,则返回空数组。

var arr = [1,2,3,4];
arr.slice(2,1);
//[]

  • splice()
    objectArray.splice(star,lenitem...);
    向数组中部插入某项,但使用splice方法的方式则有如下三种
  1. 删除:只需要指定两个参数arr.splice(star,len),删除第一项star位置,和要删除的len项数。
var colors = ['red','green','blue'];
colors.splice(1,2);
//['green','blue'];
console.log(colors)
//['red']
  1. 插入:只需要提供三个参数,Array.splice(star, 0 ,item...);指定位置star开始,删除0项,插入item项,其中item可以为多个。
 var colors = [ 'red' , 'green' , 'blue' ];
 colors.splice( 2 , 0 , 'yellow'); 
// [] 返回删除项,因为删除了0项
console.log(colors);
// ['red','green','blue','yellow'] 
//传入多项
colors.splice(3,0,'orange','blue')
//[]
console.log(colors);
//['red','green','blue','yellow','orange','blue'] 
  1. 替换:其实是删除了len项(len>0),Array.splice(star,lenitem...),同理可以传入多项去替换指定项。
 var colors = [ 'red' , 'green' , 'blue' ];
 colors.splice( 2 , 1 , 'yellow'); 
//['blue'] 返回删除的blue
cosole.log(colors);
// [ 'red' , 'green' , 'yellow' ];

6. Arrry的位置方法

  • indexof()
    从数组的开头(位置0)开始,向后查找。
var arr = [1,2,3,4,5,7,8 ];
arr.indexof(3);
//2
  • lastIndexof()
    从数组的尾部(length-1)开始,向前查找。
var arr = [1,2,3,4,5,7,8 ];
arr.lastIndexof(5);
//2

7. Array迭代方法

  • every():对数组中的每一项运行给定函数,如果该函数对每一项返回true,则返回true.
//你可以这么记,一粒老鼠屎搅坏一锅粥;哈哈
var  arr = [1,2,3,4,5,6];
 var state = arr.every(function(item,index,arrry){
    return (item > 2);
})
console.log(state) // false
  • some():对数组每一项运行给定函数,该函数有一项返回true,则返回true.
var  arr = [1,2,3,4,5,6];
 var state = arr.some(function(item,index,arrry){
    return (item = 2);
})
console.log(state) // true
  • forEach():对数组每一项给定指定函数,该方法没有返回值,本质上是for循环迭代数组一样。
var arr =  [1,2,3];
arr.forEach(function(iten,index,array){
   console.log(item,index,array);
});
//1  0   [1, 2, 3, 4, 5, 6.7]
//2  1  [1, 2, 3, 4, 5, 6.7]
//3  2   [1, 2, 3, 4, 5, 6.7]
  • filter():利用指定函数确定是否在返回的数组中包含某一项,我们叫数组过滤。
var arr = [1,2,3,4,5,6,7];
var filterArr = arr.filter(function(item,index,array){
  return (item > 2 )
})
console.log(filterArr)
//[3,4,5,6,7]
  • map():给数组每一项给定运行函数,返回每一项的函数运行结果组成的数据。
var arr = [1,2,3,4,5,6];
var mapArr = arr.map(function(item,index,array){
   return(item*2);
})
console.log(mapArr) 
//[2,4,6,8,10,12]

8. Array的归并方法

  • reduce():从数组的第一项开始,逐个遍历到最后,然后构建一个最终返回的值。
    Arr.reduce(function(p,c,index,array){},initialValue;

reduce的第一个参数是回调函数,第二个参数initialValue代表归并开始作为第一次调用 callback 的第一个参数。

var arr = [1,2,3,4,5,6,7];
var sum = arr.reduce(function(p,c,index,array){ 
  return p + c;
});
console.log(sum)
// 28
var arr = [1,2,3,4,5,6,7];
var sum = arr.reduce(function(p,c,index,array){ 
console.log(index)
  return p + c;
},10 ); //initialValue设为10
console.log(sum)
//38

注意:如果这个数组为空,运用reduce是什么情况?

var arr = [];
var sum = arr.reduce(function(p,c,index,array){ 
console.log(index)
  return p + c;
});
//报错,"Reduce of empty array with no initial value at Array.reduce"

但是我们设置初始值就不会报错了

var arr = [];
var sum = arr.reduce(function(p,c,index,array){ 
console.log(index)
  return p + c;
},0);
console.log(arr, sum); // [] 0

运行回调函数时候,p的初始值为第一项,但是index1,之后为上一次返回的值。

var arr = [1,2,3,4,5,6,7];
var sum = arr.reduce(function(p,c,index,array){ 
  return p + c;
});
console.log(sum) //28

第一次p=1,c=2,第二次p=3(第一次运行结果),c=3,依次类推,直到得到最后的返回值。

reduce的高级用法
(1)计算数组中每个元素出现的次数

let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];

let nameNum = names.reduce((pre,cur)=>{
  if(cur in pre){
    pre[cur]++
  }else{
    pre[cur] = 1 
  }
  return pre
},{})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}

(2)数组去重

let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
    if(!pre.includes(cur)){
      return pre.concat(cur)
    }else{
      return pre
    }
},[])
console.log(newArr);// [1, 2, 3, 4]

(3)将二维数组转化为一维

let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
    return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]

(3)将多维数组转化为一维

let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
   return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]

(4)、对象里的属性求和

var result = [
    {
        subject: 'math',
        score: 10
    },
    {
        subject: 'chinese',
        score: 20
    },
    {
        subject: 'english',
        score: 30
    }
];
result.reduce(function(p,c){
 return c.score+p
},0) //60
  • reduceRight():和reduce类似,只是方向相反而已。
var arr = [1,2,3,4,5,6,7];
var sum = arr.reduceRight(function(p,c,index,array){ 
  return p + c;
});
console.log(sum) //28

第一次p=7(最后一项开始),c=6,第二次p=13(第一次运行结果),c=6,依次类推,直到得到最后的返回值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  •   引用类型的值(对象)是引用类型的一个实例。   在 ECMAscript 中,引用类型是一种数据结构,用于将数...
    霜天晓阅读 1,054评论 0 1
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,233评论 0 4
  • 本章内容 使用对象 创建并操作数组 理解基本的 JavaScript 类型 使用基本类型和基本包装类型 引用类型的...
    闷油瓶小张阅读 681评论 0 0
  • 引用类型的值(对象)是引用类型的一个实例。 Object类型 创建Object类型的方式有两种。 一种是使用new...
    言大大freedom阅读 470评论 0 0
  • Array类型 除了Object之外,Array类型恐怕是ECMAScript中最常用的类型了。ECMAScrip...
    胖胖冰阅读 273评论 0 2