1

Array类型

  1. ECMAscrip与其他多数语言中数组的共同点:
    都是数据的有序列表

  2. 不同点:数组的每一项可以保存任何类型的数据,数组的大小是可以动态调整的,及随着数据的添加自动增长,以容纳新增的数据

1 创建数组

1.1 同Object一样,创建数组的方式有两种

Arrey构造函数

  1. var colors = new Array();

  2. 向Array构造函数中传递数组中应该包含的项,
    var colors = new Array('red','green','blue');

  3. 给构造函数传递一个数值,表示数组的长度(项数),
    var colors = new Array(3);

  4. 也可省略new操作符,
    var colors = Ayyay(3); var colors = Array('red');

数组字面量表示法

  1. 数组字面量表示法由一对包含数组项的方括号表示,
    var color = ['red','green','blue'];

1.2 读取和设置数组的值

要使用方括号并提供相应的值是基于0的数字索引。

var colors = ['red','blue','green'];
alert (colors[0]);
colors[2] = 'black'; //修改第三项
colors[3] = 'brown';//新增第四项

数组中的length属性很有特点:不是只读的。通过设置这个属性。可以从数组的末尾移除项,或向数组中新增项。

  1. 移除一项

    var colors = ['red','blue','green'];
    colors.length = 2;
    alert (colors[2]); //undefined

  2. 新增一项

    var colors['red','bule','green'];
    colors.length = 4;
    alert(coloes[3]);//undefined

  3. 利用length属性在末尾新增项

    var colors = ['red','blue','green'];
    colors[colors.length] = 'black';
    colors[colors.length] = 'brown';
    alert(colors[4]);//brown
    由于数组的最后一项索引始终时length-1,所以下一项的位置就是length。每当在末尾添加一项后,其length都会自动更新以反应这一变化。

检测数组

  1. 对于单一的全局作用域,也就是对于有一个网页或者一个全局作用域而言,使用instanceof操作符
    if (value instanceof Array){//对数组执行某些操作}

  2. 对于两个以上不同的执行环境,也就是如果网页中包含多个模板。从而存在两个以上不同版本的Array构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。为解决这个问题ECMAScript5新增了Array.isArray()方法。这个方法不管数组是在哪个全局执行环境中创建的,都可以确定某个值是不是数组。
    if(Array.isArray(value)){//对数组执行某些操作};

支持Array.isArray()的方法浏览器有IE9+、Firefox4+、Safari5+、Opera 10.5、和Chrome。

var colors = ['red','blue','green']; 
if(Array.isArray(colors)){
  colors[0] = 'balck';
  alert(colors[0]);
}

转换方法

所有对象都具有toLocaleString()、toString()和valueOf()方法

  • 调用数组的toString()方法:返回由数组中 '每个值的字符串' 形式 '拼接' 而成的一个以逗号分割的 '字符串'

  • 调用数组的valueOf()方法:返回的还是数组。

var aqiData = [
  ["北京", 90],
  ["上海", 50],
  ["福州", 10],
  ["广州", 50],
  ["成都", 90],
  ["西安", 100]
];
alert(aqiData.toString());
alert(aqiData.valueOf());
alert(aqiData);
console.log(aqiData.toString());
console.log(aqiData.valueOf());
console.log(aqiData);

上面第9、10行代码先显式调用了toString()方法和valueOf()方法。第11行直接将数组传递给alert()。而alert()要接收字符串参数,所以它会在后台调用数组每一项的toString()方法。由此得到与直接调用toString()方法相同的结果。

  • 调用数组的 toLocaleString()方法时,它也会创建一个由数组中 '每个值的字符串' 形式 '拼接' 而成的一个以逗号分割的 '字符串' ,与前面两个方法唯一不同之处在于取数组每一项的值调用的方法不一样,这里取数组每一项值调用的是每一项的toLocaleString()方法,而不是toString()方法,前面讲的是调用每一项的toString()方法。

var person1 = {
  toLocaleString : function(){
    return  'chenglong';
  },
  toString : function(){
    return  'lixiaolong';
  }
};
var person2 = {
  toLocaleString : function(){
    return  'lilianjie';
  },
  toString : function(){
    return  'chenzhen';
  }
};
var people = [person1,person2];
alert(people.toString());
alert(people);
alert(people.toLocaleString());
console.log(people.toString());
console.log(people);
console.log(people.toLocaleString());
  • join()指定分割符连接数组元素。只接受一个参数,即用作分割符的字符串,返回包含所有数组项的字符串。如果不给join()传入任何值或传入undefined,则使用逗号作为分割符.而IE7或更早的版本会错误的使用undefined作为分割符。

  • 如果数组中的某一项值是null或undefined,那么该值在join(),toString(),valueOf()和toLocaleString()方法返回的结果中以空字符串表示。

栈方法

ECMAScript也提供了一种让数组的行为类似于其他数据结构的方法,具体说来,数组可以表现的就像栈一样。栈是一种LIFO(后进先出)的数据结构。栈中项的插入和移除只发生在一个位置——栈的顶部。ECMAScript为数组提供了push()和pop()方法实现类似栈的行为。

  1. push()方法,可以接收任意数量的参数,把他们逐个添加到数组的末尾,并返回修改后数组的长度

  2. pop()方法,从数组的末尾移除最后一项,减少数组的length值,返回移除的项。

var colors = [];
var count = colors.push('red','green');
alert(count);//2
var item = colors.pop();
alert(item);//green
alert(colors.length);//1

队列方法

栈数据结构的访问规则是LIFO(后进先出),而另一种数据结构——队列数据结构,访问规则是FIFO(先进先出)。队列在列表的末端添加项,从列表的前端移除项。末端添加项依旧使用push()方法,shift()方法可以移除数组的第一项,并返回该项,同时将数组长度减1.

  • 结合push()方法和shift()方法可以像使用队列一样使用数组。

var colors = [];
var count = colors.push('red','green');
alert(count);//2
var item = colors.shift();
alert(item);//red
alert(colors.length);//1

ECMAScript还为数组提供了unshift()方法,unshift()与shift()作用相反,unshift()是在数组的前端添加任意多个项并返回新数组的长度。因此,同时使用unshitf()和pop()方法,可以从相反的方向模拟队列。

var colors = [];
var count = colors.unshift('red','green');
alert(count);//2
count = colors.unshift('black');
var item = colors.pop();
alert(item);//green
alert(colors.length);//2

注:IE7及更早版本unshift()会返回undefined而不是数组的心长度。IE8只在非兼容模式下返回正确的长度。

重排序方法

数组中有两个可以排序的方法,reverse()和sort()。

  • reverse()会反转数组项的顺序。

var values = [1,3,5,2,4];
values.reverse();
alert(values); //4,2,5,3,1
  • 默认情况下sort()会按升序排列数组项,但此升序非彼升序

为了实现排序,sort()会调用每个数组项的toString()转换方法,然后比较得到的字符串,以确定如何排序。

var value = [0,1,5,10,15];
value.sort();
alert(value);//0,1,10,15,5

sort()方法比较的是字符串,字符串比较,"10"位与"5"前面。sort()方法还可以接收一个比较函数作为参数,可实现我们期望的排序。

比较函数接收两个参数,如果第一个参数应该位于第二个参数之前则返回负数,如果两个参数相等则返回零,如果第一个参数应该位于第二个参数之后则返回正数。以下就是一个比较函数。

  var myArray = [0,10,5,15,1];
  function compare(value1,value2){
    if (value1<value2) {
      return -1;
    }else if (value1>value2) {
      return 1;
    }else {
      return 0;
    }
  };
  myArray.sort(compare);
  alert(myArray);//0,1,5,10,15

reverse()和sort()返回的是排序后的数组

操作方法

  • concat()方法,可以基于当前数组中的所有项创建一个新数组。具体说,这个方法会先创建当前数组的一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。1, 在没有给concat()方法添加参数的情况下,他只是复制当前数组并返回副本。2, 如果传递给concat()方法的是一个多个数组,则该方法会将这些数组中的每一项添加到结果数组中。3, 如果给concat()方法传递的不是数组,这些值会被简单的添加到结果数组的末尾。原来的数组colors(),保持不变

  var colors = ['red','blue'];
  var newColors = colors.concat('black',['yellow','brown'],['green']);
  alert(colors);//red,blue
  alert(newColors);//red,blue,black,yellow,brown,green
  • slice()方法,基于当前数组的一个或多个项创建一个新数组。slice()方法接收一个或两个参数,同concal()方法一样,原来的数组不会被影响。注意,如果slice()参数中有一个是负数,则用数组长度加上该数来确定相应位置。例一个包含5项的数组,slice(-2,-1)即slice(3,4)。如果结束位置小于起始位置,则返回空数组。

  • splice()方法,这个方法算是最强大的数组方法了。splice()方法的主要用途是向数组的中部插入项。使用的方式有如下3种。

1, 删除,可以删除任意数量的项,只需指定2个参数,要删除的第一项的位置和要删除的项数。
2, 插入,可以向指定的位置插入任意数量的项,只需提供3个参数,起始位置,0(要删除的项数),和要插入的项。如果要插入多项,可以插入任意多个项。例,splice(1,0,'red','yellow');
3, 替换,可以向指定的位置插入任意数量的项,插入的项数不必与删除的项数相等,例,splice(2,1,'red','blue');
splice()方法始终都会返回一个数组,该数组包含从原始数组中删除的项(如果没有删除任何项,就会返回一个空数组)。splice()会改变原始数组。

var colors = ['red','blue','green'];
var colors2 = colors.splice(1,2);
alert(colors2);//blue,green
var colors3 = colors.splice(0,0,'black',['brown']);
alert(colors3);//[]
alert(colors);//black,brown,red
console.log(colors3);
var colors4 = colors.splice(1,1,'yellow','purple');
alert(colors4);//brown
alert(colors);//black,yellow,purple,red

位置方法

indexOf()和lastIndexOf()方法。都接收两个参数,要查找的项和查找起点位置的索引(可选)。indexOf()从数组的0位置开始向后查,lastIndexOf()从数组的末尾开始向前查找。都返回要查找的项在数组中的位置。没有找到的情况下返回-1,在比较第一个参数与数组中的项时,使用全等操作符(必须严格相等)。支持这两种方法的浏览器有IE9+,fireFox2+,Safari3+,Opera9.5+,Chrome。

  var person = {name:'Nicholas'};
  var people = [{name:'Nicholas'}];
  var morePeople  = [person];
  alert(people.indexOf(person));//-1
  alert(morePeople.indexOf(person));//0
  alert(morePeople.indexOf({name:'Nicholas'}));//-1
  console.log(morePeople);//[Object]

迭代方法

ECMAScript为数组定义了5个迭代方法。每个方法都接收两个参数,要在每一项上运行的函数和运行该函数的作用域对象——影响this的值(可选)。传入这些方法的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。根据使用的方法不同,这个函数执行后的返回值可能会也可能不会影响访问的返回值。

  1. every():对数组中的每一项运行给定的函数,如果该函数对每一项都返回true,则返回 true.

  2. filter():对数组的每一项都运行给定数组,返回 该函数会返回true的项 组成的数组。

  3. forEach():对数组的每一项运行给定的函数,这个方法没有返回值。

  4. map():对数组每一项运行给定函数,返回 每次函数调用的结果 组成的数组。

  5. some():对数组中的每一项运行给定的数组,如果该函数对任一项返回true,则返回true.

  var numbers = [1,2,3,4,5,4,3,2,1];
  var everyResult = numbers.every(function(item,index,array){
    console.log(item);      
    return item > 2;
  });
  var someResult = numbers.some(function(item,index,array){
    console.log('someResult'+item);  
    return item > 2;
  });
  alert(everyResult);
  alert(someResult);
  var aqiData = [
  ["北京", 90],
  ["上海", 50],
  ["福州", 10],
  ["广州", 50],
  ["成都", 90],
  ["西安", 100]
];
  var filterResult = aqiData.filter(function(item,index,array){
    //console.log(item[1]);
    return item[1] > 60;
  });
  alert(filterResult);
  
  var numbers = [1,2,3,4,5,4,3,2,1];
  numbers.forEach(function(item,index,array){
    if (item>3) {
      alert(item);
    }
  });

支持这些迭代方法的浏览器有IE9+、FireFox2+、Safari3+、Opera9.5+、Chrome

缩小方法

ECNAScript还增加了两个缩小方法,reduce()和reduceRight().这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。其中reduce()从数组的第一项开始,逐个遍历到最后,而reduceRight()从数组的最后一项开始,向前遍历到第一项。

  • 这两个方法都接收两个参数:一个在每一项上调用的函数和最为缩小基础的初始值(可选),传递给他们的函数接收4个参数:前一个值,当前值,项的索引和当前对象。

  • 这个函数返回的任何值都会最为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上,因此第一参数就是数组的第一项,第二个参数就是数组的第二项。
    //执行数组中所有值之和的操作

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev,cur,index,array){
  return prev+cur;
});
  alert(sum);//15

第一次访问函数,prev是1,cur是2;第二次,prev是3(1+2结果),cur是3(数组第三项)
支持这些迭代方法的浏览器有IE9+、FireFox3+、Safari4+、Opera10.5+、Chrome

参考:JS高级程序设计


下客介
68 声望4 粉丝