Javascript 高级编程 5章86页 【Array类型】

132 阅读7分钟

ECMAScript数组

  • 每一项可以保存任何类型的数据
  • 大小可以动态调整。随着数据的添加,自动增长以容纳新增数据

创建数组

方式一:Array的构造函数

var colors = new Array();
var colors = new Array(20);
var colors = new Array("red", "blue", "green");

方式二:Array的构造函数,省略new

var colors = Array();
var colors = Array(20);
var colors = Array("red", "blue", "green");

方式三:数组字面量表示法

var colors = ["red", "blue", "green"];
var names = [];

用数组字面量表示法时,里面填数值容易出错!建议不要用这种语法!

  • IE8及之前版本,在ECMAScript实现数组方面有Bug!
  • IE与其他浏览器也不一致
//别这样用!
//会创建包含1,2的数组,或者会创建包含1,2, undefined的数组
var values = [1, 2, ]; 

//别这样用!
//会创建包含5个undefined的数组,或者会创建包含6个undefined的数组
var options = [,,,,,];

读取和设置数组的值

var colors = ["red",  "blue", "green"];
alert(colors[0]);
colors[2] = "black";
//超出索引,自动增加数组长度,并添加值
colors[3] = "brown";

数组的长度

var colors = ["red",  "blue", "green"];
alert(colors.length)
  • 数组长度保存在length属性中
  • length属性,不是只读的
  • 可以通过设置length属性
    • 从数组末尾移除项
    • 向数组中添加新项
  • 数组最多可以包含 4294967295 个项
var colors = ["red",  "blue", "green"];
colors.length = 2;
alert(colors[2]); // 没指定值的位置,就是undefined 

colors[colors.length] = "black";
var colors = ["red",  "blue", "green"];
colors[99] = "black";
alert(colors.length); //100

确定某个对象是不是数组

  • instanceof
    • 只适用于只有一个全局执行环境 (一个网页)
  • Array.isArray()
    • 也适用于有多个全局执行环境(网页中包含多个框架,存在两个以上不同版本的Array构造函数
if (value instanceof Array) {
    //...
}
if(Array.isArray(value)) {
    //...
}

数组的 toString(), toLocaleString(), valueOf()

所有对象都具有 toString(), toLocaleString(), valueOf() 方法 数组的:

  • toString(),数据的每一项调用toString(), 然后逗号分隔,拼接成字符串
  • toLocaleString(),数据的每一项调用toLocaleString(), 然后逗号分隔,拼接成字符串
  • valueOf(), 仍然返回数组
  • join(), 数据的每一项调用toString(), 然后用指定的分隔符分隔,拼接成字符串
    • 不指定分隔符时,默认为逗号
var colors = ["red", "blue", "green"];

alert(colors.toString());
alert(colors.valueOf());
alert(colors.toLocaleString());
alert(colors.join("||"));

用数组 模拟 栈: push() 和 pop()

数组专门提供了push()pop()方法,以便实现类似于栈的行为

  • push():
    • 可以接收任意数量的参数
    • 把它们逐个添加到数组末尾
    • 返回修改后数组的长度
  • pop():
    • 从数组末尾移除最后一项
    • 减少数组的长度
    • 然后返回移除的项
var colors = new Array();
var count =  colors.push("red", "green");
alert(count.length);  // 2

count = colors.push("black");
alert(count.length);  // 3

var item = colors.pop();
alert(item); // black
alert(count.length);  // 2

用数组 模拟 队列

方法一:数组的 末尾进 前头出push()shift()

  • push(): 向数组末端添加项
  • shift(): 移除数组中的第一个项,并返回该项,同时数组长度减1
var colors = new Array();
var count =  colors.push("red", "green");
alert(count.length);  // 2

count = colors.push("black");
alert(count.length);  // 3

var item = colors.shift()d;
alert(item); //"red"
alert(count.length);  // 2

方法二:数组的 前头进 末尾出unshift()pop()

  • pop(): 从数组末尾移除最后一项, 并返回该项,同时数组长度减1
  • unshift(): 在数组前端添加任意个项,并返回新数组长度
var colors = new Array();
var count =  colors.unshift("red", "green");
alert(count.length);  // 2

count = colors.unshift("black");
alert(count.length);  // 3

var item = colors.pop();
alert(item); //"green"
alert(count.length);  // 2

排序方法 reverse() 和 sort()

reverse()

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

sort()

  • 默认,升序排列。对每一项调用tostring(), 然后比较得到的字符串。
  • 另外,还可以接收一个比较函数作为参数
var values = [0, 1, 5, 10, 15];
values.sort();
alert(values); // 0, 1, 10, 15, 5
var values = [0, 1, 5, 10, 15];
values.sort(compare);
alert(values); // 0, 1, 5, 10, 15

比较函数:

  • 接收两个参数。
  • 第一个参数位于第二个参数之前,返回负数
  • 第一个参数和第二个参数相等,返回0
  • 第一个参数位于第二个参数之前,返回正数
function compare(value1, value2) {
    if (value1 < value2) {
        return -1;
    } else if (value1 >  value2) {
        return 1;
    } else {
        return 0;
    }
}

对于数值类型,或者其valueOf()返回数值类型的对象类型,可以用如下更简单的比较函数

function compare (value1, value2) {
    return value2 - value1;
}

操作方法

concat()

基于当前数组,创建一个新数组

  • 先创建一个当前数组的副本
  • 接受任意以下各种参数,并添加到数组末尾
    • 一个数组
    • 多个数组
    • 非数组的单值
var colors = ["red", "green", "blue"];
var colors2 = colors.concat("yellow", ["black", "brown"]);

alert(colors); //红绿蓝
alert(colors2); //红绿蓝黄黑棕

slice()

基于当前数组,创建一个新数组

  • 不会影响原始数组
  • 接受以下参数。返回的项不包括结束位置上那项。
    • 起始位置和结束位置。
var colors = ["red", "green", "blue""yellow", "purple"];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1, 4);

alert(colors2); //绿蓝黄紫
alert(colors3); //绿蓝黄

用 slice 删除。只需指定:

  • 要删除的 第一项的位置
  • 要删除的 项数
var colors = ["red", "green", "blue"];
var removed = colors.slice(0, 1);   //删除第一项

alert(colors); //绿蓝
alert(removed); //红

用 slice 插入。只需指定:

  • 起始位置
  • 0 (表示 要删除的项数。这里不删除)
  • 要插入的项
    • 如果插入多项,后面还可以传入任意多个项
var colors = ["green", "blue"];
var removed = colors.slice(1, 0, "yellow", "orange");   //从位置1开始,插入两项

alert(colors); //绿黄橙蓝
alert(removed); //空数组

用 slice 替换。只需指定:

  • 起始位置
  • 要删除的项数
  • 要插入的任意数量的项
    • 插入的项数不必与删除的项数相等
var colors = ["green", "yellow", "orange", "blue"];
var removed = colors.slice(1, 1, "red", "purple");   //删除从位置1的开始的1项,再在位置1插入两项

alert(colors); //绿红紫橙蓝
alert(removed); //黄

位置方法

  • indexOf(): 从数组开头开始向后查找
  • lastIndexOf(): 从数组末尾开始向前查找

  • 都接收
    • 要查找的 项
    • 要查找的 起点位置 (可选)
  • 都返回
    • 要查找的项在数组中的位置
    • -1 (没找到时)
  • 查找时,使用全等操作符(===)来进行比较
var numbers= [1,2,3,4,5,4,3,2,1];

alert(numbers.indexOf(4)); // 3
alert(numbers.lastIndexOf(4)); // 5

alert(numbers.indexOf(4, 4)); // 从位置4开始往后找,结果为5
alert(numbers.lastIndexOf(4, 4)); // 从位置4开始往前找,结果为3
var person = { name : "Nicholas" };
var people = [{ name : "Nicholas" }];
var morePeople = [person];

alert(people.indexOf(person));  //-1
alert(morePeople.indexOf(person));  //0

迭代方法

以下5个迭代方法,都是 对数组中的每一项 运行给定的函数。 这5个迭代方法,都接收2个参数:

  • 给定的函数
  • 运行该函数的作用域对象 (可选)。这影响this的值 给定的函数,都接收3个参数:
  • 数组项的值
  • 该项在数组中的位置
  • 数组对象本身

以下5个迭代方法,都 不会修改数组中包含的值 every():

  • 如果该函数 对每一项 都返回true, 则返回true filter():
  • 返回 对该函数返回为true的项 组成的数组 forEach():
  • 没有 返回值 map():
  • 返回 该函数返回的结果 组成的数组 some():
  • 如果该函数 任意一项 都返回true, 则返回true

var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];

var everyResult = numbers.every(function(item, index, array){
    return (item > 2);
});
alert(everyResult); // false

var someResult = numbers.some(function(item, index, array){
    return (item > 2);
});
alert(someResult); // true

var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];

var filterResult = numbers.filter(function(item, index, array){
    return (item > 2);
});
alert(filterResult); // [3, 4, 5, 4, 3]
var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];

var mapResult = numbers.map(function(item, index, array){
    return (item * 2);
});
alert(mapResult); // [2, 4, 6, 8, 10, 8, 6, 4, 2]

归并方法

  • reduce(): 从数组第一项开始,遍历到最后
  • reduceRight(): 从最后一项开始,向前遍历到第一项

迭代数组的所有项,构建一个最终返回的值

每一项 调用某个函数的返回值,会自动 作为该函数的第一个参数 传递给 下一项

接收2个参数:

  • 在每一项上 调用的 函数
    • 此函数 接收4个参数:
      • 前一个值
      • 当前值
      • 项的索引
      • 数组对象
  • 初始值 (可选)
var values = [1, 2, 3, 4, 5];
var sum = values.reduce(function(prev, cur, index, array) {
    return prev + cur;
});
alert(sum); //15
var values = [1, 2, 3, 4, 5];
var sum = values.reduceRight(function(prev, cur, index, array) {
    return prev + cur;
});
alert(sum); //15