数组原型:
自定义数组原型函数,给所有数组添加公共方法
Array.prototype.unique = function () { var arr = []; // 临时数组 - 存放去重后的数据 for(var i = 0, len = this.length; i < len; i++){ // 数组的indexOf有兼容性问题, 未检索到则返回 -1 if ( arr.indexOf( this[i] ) == -1 ) { arr.push( this[i] ); } } return arr; }; var codeArr = [3,1,4,1,5,9,2,6,5,5,5,6,9,1,1,1,3]; console.log( codeArr.unique() ); // [3, 1, 4, 5, 9, 2, 6]
A. 定义方式;
var arr = []; // 数组字面量 var arr = new Array(); // 数组构造函数
B. 数组的读和写
arr[num] // 不可以溢出读 结果undefined arr[num] = xxx; // 可以溢出写
改变原数组方法:
1. arr.push()、arr.pop()
arr.push() 方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。 var arr = []; arr.push(1); // 1 arr.push("A"); // 2 arr.push(true, {}); // 4 console.log( arr ); // ["1", "A", true, {}]
模拟数组方法:
Array.prototype.push = function (){ for( var i=0;i<arguments.lenght;i++){ this[this.length] = arguments[i]; } return this.length; }
arr.pop() 方法用于删除数组的最后一个元素,并返回该元素。
var arr = ["A", "B", "C"]; arr.pop(); // "C" console.log( arr ); // ["A", "B"] // 空数组使用 pop() 方法,不会报错,而是返回 undefined [].pop(); // undefined
2. arr.shift()、arr.unshift()
arr.shift() 方法用于删除数组的第一个元素,并返回该元素。
var arr = ["A", "B", "C"]; arr.shift(); // "A" console.log( arr ); // ["B", "C"]
arr.unshift() 方法用于在数组的第一个位置添加元素,并返回添加新元素后的数组长度。
var arr = ["A", "B", "C"]; arr.unshift("H"); // 4 console.log( arr ); // ["H", "A", "B", "C"] // 添加多个 arr.unshift("Y", "X"); console.log( arr ); // ["Y", "X", "H", "A", "B", "C"]
3. arr.sort([fn]);
arr.sort() 方法对数组成员进行排序,默认是按照字典顺序排序。
["d", "c", "b", "a"].sort(); // ["a", "b", "c", "d"] [6, 5, 4, 3, 2, 1].sort(); // [1, 2, 3, 4, 5, 6] [11, 101].sort(); // [101, 11] [10111, 1101, 111].sort(); // [10111, 1101, 111] 默认排序不是按照大小排序,而是按照字典顺序。 也就是说,数值会被先转成字符串,再按照字典顺序进行比较,所以 101 排在 11 的前面
sort() 自定义方式排序
var arr = [10111, 1101, 111]; arr.sort(function (a, b) { // 1. 必须写两个形参,表示进行比较的两个数组成员 // 2. 看返回值 // 1) 大于 0, 表示第一个排在第二个后面 // 2) 其他情况, 都是第一个排在第二个前面 return a - b; }); // [111, 1101, 10111]
数组中的对象数据:
var arr = [ { name: "张三", age: 30 }, { name: "李四", age: 24 }, { name: "王五", age: 28 } ]; arr.sort(function (a, b) { return a.age - b.age; }); // [ // { name: "李四", age: 24 }, // { name: "王五", age: 28 }, // { name: "张三", age: 30 } // ]
4. arr.reverse()
用于颠倒排列数组元素,返回改变后的数组
var arr = ["A", "B", "C"]; arr.reverse(); // ["C", "B", "A"]
5. arr.splice(从第几位开始, 截取长度, 切口处添加新数据)
用于删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素
var arr = ["A", "B", "C", "D", "E", "F"]; // 一个参数时: 删除当前位置后面所有元素 arr.splice(2); // ["C", "D", "E", "F"] // 一个参数时: 负数,表示从倒数位置开始删除 arr.splice(-3); // ["D", "E", "F"] // 指定删除长度 arr.splice(1, 2); // ["E", "F"] // 从第一个位置 E 开始删除2个元素 arr.splice(1, 0); // ["E", "F"] // 截取长度为0是,表示不删除 // 从数组的第一个位置添加两个新元素 arr.splice(1, 0, "A", "B"); // ["E", "A", "B", "F"] // 从第一个位置删除2个元素,然后添加新元素 arr.splice(1, 2, "V", "V", "M"); // ["E","V","V","M","F"]
不改变原数组的方法:
1. arr.concat()
用于多个数组合并。将新添加的成员,添加到原数组成员的后面, 然后返回一个新数组
['hello'].concat(['world]); // ['hello', 'world'] ['hello'].concat(['world'], ['!']); // ['hello','world','!'] [].concat({a: 1}, {b: 2}); // [{a: 1}, {b: 2}] [2].concat({a: 1}); // [2, {a: 1}] [1,2,3].concat(4,5,6); // [1, 2, 3, 4, 5, 6]
如果数组成员包括对象, concat 方法返回当前数组的一个浅拷贝。指的是新数组拷贝的是对象的引用。
注意:改变原对象以后,信数组跟着改变。
var oldArr = [{ a: 1}]; var newArr = oldArr.concat(); oldArr[0].a = 10; console.log( newArr[0].a );
2. arr.join()
指定参数作为分隔符,把数组转成字符串;默认用逗号分隔
var arr = [1, 2, 3, 4]; arr.join(' '); // '1, 2, 3, 4' arr.join('|'); // '1 | 2 | 3 | 4' arr.join(); //'1,2,3,4' // 如果数组成员是undefined或null或空位,会被转成空字符串 [undefined, null].join('#'); // '#' ['A', , 'B'].join('-'); // 'a--b'
3. arr.toString() 返回数组的字符串形式
var arr = [1, 2, 3, 4]; arr.toString(); // '1,2,3,4' var arr = [1, 2, 3, [4,5,6]]; arr.toString(); // '1,2,3,4,5,6'
4. arr.slice(从该位开始截取, 截取到该位);
用于提取目标数组的一部分,返回一个新数组;
var arr = ['a','b','c']; // 没有参数,返回原数组的拷贝 arr.slice(); // ['a','b','c'] // 如果省略第二个参数,则一直返回到数组的最后一个成员 arr.slice(0); // ['a','b','c'] arr.slice(1); // ['b','c'] // 包前不包后, 数组的第一位到第二位(不包含第二位) arr.slice(1, 2); // ['b'] arr.slice(2, 6); // ['c'] // 支持负数,表示倒数计算的位置 arr.slice(-2); // ['b','c'] arr.slice(-2,-1); // ['b'] // 第一个参数大于等于数组的长度 // 或 第二个参数小于第一个参数,则返回空数组 arr.slice(4); // [] arr.slice(2, 1); // []
slice 方法的一个重要应用,是将类数组的对象转为真正的数组。
var arr = { 0: 'a', 1: 'b', length: 2 }; Array.prototype.slice.call(arr); // ['a', 'b'] Array.prototype.slice.call(document.querySelectorAll('div')); Array.prototype.slice.call(arguments);
#### 类数组
1. 属性要为索引(数字)属性, 必须有length
2. 不具有数组所具有的方法
可以给类数组添加数组方法,如push: Array.prototype.push
如果添加splice方法则就跟数组长一样了 [1, 2, 3]
var obj = { "0": 'a', "1": 'b', "2': 'c', "length": 3, "push": Array.prototype.push, "splice": Array.prototype.splice } 好处: (类数组push是根据length来替换) Array.prototype.push = function (target) { obj[obj.length] = target; obj.length ++; }
数组的其它方法:
arr.map(); // 不改变原数组
把数组的所有成员依次传入参数函数,把每次执行的结果组成一个新数组返回。
var numbers = [1, 2, 3]; numbers.map(function (n) { return n + 1; }); // [2, 3, 4]
函数作为参数调用时, 可以传入三个参数(当前成员, 当前位置, 数组本身)
[1,2,3].map(function(elem, index, arr) { return elem * index; }); // [0, 2, 6]
map 方面可以接受第二个参数,用来绑定回调函数内部的 this 变量
var arr = ['a','b','c']; [1,2].map(function(n) { // n 是.map前面数组的每一项, this指向arr数组 return this[n]; }, arr); // ['b', 'c']
遇到数组空位,跳过空位,不执行回调
var f = function (n) { return 'a'; } [1, undefined, 2].map(f); // ['a', 'a', 'a'] [1, null, 2].map(f); // ['a', 'a', 'a'] [1, , 2].map(f); // ['a', , 'a']
arr.forEach(); 数组遍历
forEach 方法与 map 方法很相似, 对数组所有成员进行遍历。
forEach 方法没有返回值,值用来操作数据。
// 第一个参数是函数,有三个参数:(当前值, 当前位置, 数组本身) [0, 5, 3].forEach(function(elem, index, arr) { console.log('['+index+'] = ' + elem); }); // [0] = 0 // [1] = 5 // [2] = 3
可以接受第二个参数,用来绑定回调函数内部的 this 变量
var out = []; [0, 5, 3].forEach(function(n) { this.push(n * n); }, out); console.log(out); // [0, 25, 9]
注意:
1. forEach 方法会跳过数组的空位
2. forEach 方法无法中断循环, 总会将所有成员遍历完。
arr.filter(); 过滤数组成员
用于过滤数组成员,满足条件的成员组成一个新数组返回。
第一个参数是回调函数,必填。遍历所有成员,满足条件的成员组成一个新数组返回。
[1,2,3,4,5].filter(function(elem) { return (elem > 3); }); // [4, 5]
返回数组中所有布尔值为 true 的成员
[0, 1, 'a', false, null].filter(Boolean); // [1, 'a']
回调函数可以接受三个参数: (当前成员,当前位置,数组本身)
[1,2,3,4,5].filter(function(elem, index, arr) { return index % 2 === 0; }); // [1, 3, 5]
接受第二个参数,用来改变回调函数中的 this 变量
var obj = { Max: 3 }; var arr = [0, 5, 3, 4, 16]; arr.filter(function(n) { // this 指向 obj if(n > this.Max) { return true; } }, obj); // [5, 4, 16]
arr.some(fn)、every(fn);
依次遍历数组成员,回调函数接受三个参数: (当前成员,当前位置,数组本身)
返回一个布尔值.
可以接受第二个参数,用来改变回调函数中的 this 变量
some 方法是只要一个满足条件就返回true, 否则返回 false
var arr = [1, 2, 3, 4, 5]; arr.some(function (elem, index, arr) { return elem >= 3; }); // true;
every 方法是全部满足条件才返回true,否则返回 false
var arr = [1, 2, 3, 4, 5]; arr.some(function (elem, index, arr) { return elem >= 3; }); // false;
对于空数组, some 方法返回 false , every 方法返回 true, 回调函数不执行
function isEven(x) { return x % 2 === 0; } [].some(isEven); // false [].every(isEven); // true
reduce()、reduceRight() 返回最终的统计结果
reduce 是从左到右处理(第一个到最后一个)
reduceRight 是从右到左处理(最后一个到第一个)
第一个参数是一个回调函数, 接受四个参数
1. 积累变量, 默认第一个成员 (必须)
2. 当前变量, 默认第二个成员 (必须)
3. 当前位置(从0开始)
4. 原数组
[1, 2, 3, 4, 5].reduce(function (a, b) { console.log(a, b); return a + b; }); // 1 2 // 3 3 // 6 4 // 10 5 //最后结果:15
第二个参数,指定初始值,在初始值的基础上累加
[1, 2, 3, 4, 5].reduce(function (a, b) { console.log(a, b); return a + b; }, 10); // 25
空数组娶不到初始值,reduce方法会报错。
function add(prev, cur) { return prev + cur; } [].reduce(add); // TypeError: Reduce of empty array with no initial value [].reduce(add, 1); // 默认返回初始值 // 1
arr.indexOf(查找元素, 指定位置)、arr.lastIndexOf(查找元素,指定位置) // IE8不兼容, 会报错
返回给定元素在数组中第一次出现的位置,如果没有找到则返回 -1
var arr = ["a", "b", "c"]; arr.indexOf("b"); // 1 arr.indexOf("v"); // -1 // 指定搜索的开始位置 arr.indexOf("a", 1); // -1
lastIndexOf 方法返回给定元素在数组中最后一次出现的位置,如果没有找到则返回-1
var a = [2, 5, 9, 2]; a.lastIndexOf(2) // 3 a.lastIndexOf(7) // -1