## Array类型 ECMAScript数组的每一项可以保存任何类型的数据,也就是说,而且数组的大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新增数据。 ``` var colors = [1, 'tg', {}]; ``` 在上面的例子中,数组中保存了数值、字符串和对象。 **1、初始化数组实例** 创建数组的基本方式有多种: **(1)使用Array构造函数** 当传递一个参数时,如果传递的参数是数值,则会按照该数值创建包含给定项数的数组;如果是其他类型的参数,则会创建包含那个值的数组(只有一项)。 ``` var colors1 = new Array(); var colors2 = new Array(20); var colors3 = new Array('a',1); ``` 在上面的代码中,第一行代码创建了一个空数组;第二行代码创建了一个length为20的属性;第三行代码创建了一个包含两个数组项的数组。 可省略new,但不推荐 ``` var colors = Array(); ``` **(2)使用数组字面量** 使用数组字面量表示法,由一对包含数组项的方括号表示,多个数组项之间用逗号隔开。 ``` var colors = []; // 空数组 var colors2 = [1,2]; // 包含两个数组项的数组 ``` 数组的项数保存在其`length`属性中,不小于0,可读写。可通过减小来移除数组项。所有数组项默认是undefined(在不设置的情况下)。 **2、检测数组(Array.isArray())** `Array.isArray()`判断是否是数组,传入一个数组作为参数。 ``` var colors = []; console.log(Array.isArray(colors)); // true console.log(Array.isArray(1)); // false ``` **3、Array实例的方法** **(1)valueof()** `varlueOf()`方法返回数组本身 ``` var arr = [1,'test']; console.log(arr.valueOf()); // [1,"test"] ``` **(2)toStirng()** 将数组中每个值的字符串拼接成一个字符串,中间以逗号隔开 ``` var arr = [1,'test']; console.log(arr.toString()); // 1,test ``` **(3)push()** 用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度,该方法会改变原数组。 ``` var arr = []; console.log(arr.push(3)); // 1 console.log(arr.push(true)); // 2 console.log(arr); // [3, true] ``` **(4)pop()** 用于删除数组的最后一个元素,并返回该元素,该方法会改变原数组。 ``` var arr = [1,'test']; console.log(arr.pop()); // "test" console.log(arr); // [1] ``` 对空数组使用pop方法,不会报错,而是返回undefined。 **(5)join()** 以参数作为分隔符,将所有数组成员组成一个字符串返回。如果不提供参数,默认用逗号分隔。 ``` var arr = [1, 'test']; console.log(arr.join()); console.log(arr.join('||')); ``` 注意:如果数组成员是undefined或null或空位,会被转成空字符串。 **(6)concat()** 用于多个数组的合并。它将新数组的成员,添加到原数组的尾部,然后返回一个新数组,原数组不变。 ``` var arr = [1,'test']; console.log(arr.concat([2],['a'])); // [1, "test", 2, "a"] ``` 除了接受数组作为参数,concat也可以接受其他类型的值作为参数。它们会作为新的元素,添加数组尾部。 ``` var arr = [1,'test']; console.log(arr.concat('b',[2])); // [1, "test", "b", 2] ``` **(7)shift()** 用于删除数组的第一个元素,并返回该元素,该方法会改变原数组。 ``` var arr = [1,'test']; console.log(arr.shift()); // 1 console.log(arr); // ["test"] ``` **(8)unshift()** 用于在数组的第一个位置添加元素,并返回添加新元素后的数组长度,该方法会改变原数组。 ``` var arr = [1,'test']; console.log(arr.unshift('a')); // 3 console.log(arr); // ["a", 1, "test"] ``` `unshift()`可添加多个元素: ``` var arr = [1,'test']; console.log(arr.unshift('a','b')); // 4 ``` **(9)reverse()** `reverse()`用于颠倒数组中元素的顺序,返回改变后的数组,该方法会改变原数组。 ``` var arr = [1,'test']; console.log(arr.reverse()); // ["test",1] ``` **(10)slice()** `slice()`用于提取原数组的一部分,返回一个新数组,原数组不变。 第一个参数为起始位置(从0开始),如参数是负数,则表示倒数计算的位置。 第二个参数为终止位置(但该位置的元素本身不包括在内),如参数是负数,则表示倒数计算的位置。 如果省略第二个参数,则一直返回到原数组的最后一个成员。负数表示倒数第几个。 如果参数值大于数组成员的个数,或者第二个参数小于第一个参数,则返回空数组。 ``` var arr = ['a','b','c','d']; console.log(arr.slice(1,3)); // ["b", "c"] console.log(arr.slice(2)); // ["c", "d"] console.log(arr.slice(-2,-1)); // ["c"] console.log(arr.slice(2,1)); // [] ``` **(11)splice()** `splice()`用于删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员,返回值是被删除的元素,该方法会改变原数组。 第一个参数是删除的起始位置,如果是负数,就表示从倒数位置开始删除 第二个参数是被删除的元素个数。 如果后面还有更多的参数,则表示这些就是要被插入数组的新元素。 如只是单纯地插入元素,splice方法的第二个参数可以设为0。 如果只提供第一个参数,等同于将原数组在指定位置拆分成两个数组。 ``` var arr = ['a','b','c','d']; console.log(arr.splice(1,1)); // ["b"] console.log(arr); // ["a", "c", "d"] var arr = ['a','b','c','d']; console.log(arr.splice(1,1,'f')); // ["b"] console.log(arr); // ["a", "f", "c", "d"] var arr = ['a','b','c','d']; console.log(arr.splice(1,0,'h')); // [] console.log(arr); // ["a", "h", "b", "c", "d"] ``` **(12)sort()** `sort()` 对数组成员进行排序,默认是按照字典顺序排序。排序后,原数组将被改变。 如果想让sort方法按照自定义方式排序,可以传入一个函数作为参数,表示按照自定义方法进行排序。该函数本身又接受两个参数,表示进行比较的两个元素。如果返回值大于0,表示第一个元素排在第二个元素后面;其他情况下(小于或等于),都是第一个元素排在第二个元素前面。 ``` var arr = ['5','8','9','2']; console.log(arr.sort()); // ["1", "2", "4", "5"] var newArr = arr.sort(function(a, b) { returnb - a; }); console.log(newArr); // ["5", "4", "2", "1"] ``` 注意:sort方法不是按照大小排序,而是按照对应字符串的字典顺序排序。也就是说,数值会被先转成字符串,再按照字典顺序进行比较。 **(13)map()** `map()`对数组的所有成员依次调用一个函数,根据函数结果返回一个新数组。 接受一个函数作为参数。该函数调用时,map方法会将其传入三个参数,分别是当前成员、当前位置和数组本身 ``` var arr = [1,2,3]; var newArr = arr.map(function(v){ return v - 1; }); console.log(newArr); // [0, 1, 2] ``` **(14)forEach()** `forEach()`遍历数组的所有成员,执行某种操作,参数是一个函数。它接受三个参数,分别是当前位置的值、当前位置的编号和整个数组。 ``` var arr = ['a', 'b']; arr.forEach(function(value,index){ console.log(index + ':' + value); }); // 0 : "a" 1 : "b" ``` **(15)filter()** `filter()`参数是一个函数,所有数组成员依次执行该函数,返回结果为true的成员组成一个新数组返回。该方法不会改变原数组。 filter方法的参数函数可以接受三个参数,第一个参数是当前数组成员的值,这是必需的,后两个参数是可选的,分别是当前数组成员的位置和整个数组。 ``` var arr = [1,2,3]; var newArr = arr.filter(function(v){ return (v > 2); }); console.log(newArr); // [3]; ``` **(16)some()、every()** `some()`用来判断数组成员是否符合某种条件。接受一个函数作为参数,所有数组成员依次执行该函数,返回一个布尔值。 该函数接受三个参数,依次是当前位置的成员、当前位置的序号和整个数组。只要有一个数组成员的返回值是true,则整个some方法的返回值就是true,否则false。 ``` var arr = [1,2,3]; var bool = arr.some(function(v){ return (v == 3); }); console.log(bool); // true ``` `every()`用来判断数组成员是否符合某种条件。接受一个函数作为参数,所有数组成员依次执行该函数,返回一个布尔值。 该函数接受三个参数,依次是当前位置的成员、当前位置的序号和整个数组。所有数组成员的返回值都是true,才返回true,否则false。 ``` var arr = [1,2,3]; var bool = arr.every(function(v){ return (v == 3); }); console.log(bool); // false var bool2 = arr.every(function(v){ return (v > 0); }); console.log(bool2); // true ``` some和every方法还可以接受第二个参数,用来绑定函数中的this关键字。 **(17)reduce()、reduceRight()** `reduce()`依次处理数组的每个成员,最终累计为一个值。从左到右处理(从第一个成员到最后一个成员) `reduceRight()`依次处理数组的每个成员,最终累计为一个值。从右到左(从最后一个成员到第一个成员) 两个方法的第一个参数是一个函数,该函数可接收四个参数: 1. 累积变量,默认为数组的第一个成员 2. 当前变量,默认为数组的第二个成员 3. 当前位置(从0开始) 4. 原数组 对`reduce()`: ``` var arr = [1, 2, 3, 4, 5]; var total = arr.reduce(function(x, y){ console.log(x, y) return x + y; }); console.log(total); // 1 2 // 3 3 // 6 4 // 10 5 //最后结果:15 ``` 对`reduceRight()`: ``` var arr = [1, 2, 3, 4, 5]; var total = arr.reduceRight(function(x, y){ console.log(x, y) return x + y; }); console.log(total); // 5 4 // 9 3 // 12 2 // 14 1 // 15 ``` 两个方法还可传入第二个参数,表示累积变量的初始值: **(18)indexOf()、lastIndexOf()** `indexOf()`返回给定元素在数组中第一次出现的位置,如果没有出现则返回-1。可以接受第二个参数,表示搜索的开始位置 `lastIndexOf()`返回给定元素在数组中最后一次出现的位置,如果没有出现则返回-1。可以看作是从最后位置开始搜索。 ``` var arr = ['a', 'b', 'a', 'c']; console.log(arr.indexOf('a')); // 0 console.log(arr.indexOf('a',1)); // 2 console.log(arr.lastIndexOf('a')); // 2 ```