老文章恢复
数组太常见了,以至于经常忽略它
# 声明定义 ↵
00// 调用构造函数声明数组 01var a = new Array(); // √ 长度是0 是空数组 02var b = new Array(3); // length is 3 03var s = new Array("1", "2"); // 其值是 ["1", "2"] 04 05// 或者简单地把字面量赋过去 06var colors = ["red", "blue", "green"]; 07var stack = []; // 空数组 08 09// length 长度不是只读,可以被赋值。 10// 给length赋值的结果是数组变长或者变短。 11// 变短 末项会变成undefined 12var colors = ["red", "blue", "green"]; 13colors.length = 2; 14console.log(colors[2]); // undefined 15 16// 变长 多余的末项也是undefined 17var colors002 = ["red", "blue", "green"]; 18colors002.length = 4; 19console.log(colors001[3]); // undefined
# 检测 ↵
js的数组也是对象。所以就出现了“确定某个对象是不是数组”的问题。
00if (colors instanceof array) { 01 // if colors is array 02 // do something to colors 03}
typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型。
它返回值是一个字符串,该字符串说明运算数的类型。
它返回值是一个字符串,该字符串说明运算数的类型。
typeof 一般只能返回如下几个结果:
number, boolean, string, function, object, undefined
我们可以使用 typeof 来获取一个变量是否存在,如:
00if(typeof a!="undefined"){ 01 alert("ok") 02}
不建议去使用 if(a) 因为如果 a 不存在(未声明)则会出错,对于 Array, Null 等特殊对象使用 typeof 一律返回 object,这正是 typeof 的局限性。
除了上述的判断方法外,更推荐用
Array.isArray()
进行判断00Array.isArray(colors) // true
# 转换 ↵
00var colors = ["red", "blue", "green"]; 01console.log(colors.toString()); // red,blue,green 02console.log(colors.valueOf()); // red,blue,green 03console.log(colors); // red,blue,green 04 05// toLocaleString 06var personA = { 07 toLocaleString: function(){ 08 return "nachi"; 09 }, 10 toString: function(){ 11 return "なち"; 12 } 13} 14var personB = { 15 toLocaleString: function(){ 16 return "nomico"; 17 }, 18 toString: function(){ 19 return "のみこ"; 20 } 21} 22var persons = [personA, personB]; 23console.log(persons); // ["なち", "のみこ"] 24console.log(persons.toString()); // なち,のみこ 25console.log(persons.toLocaleString()); // nachi,nomico

执行结果
# 栈 ↵
同时使用
pop
push
可以实现入栈出栈操作。00var Stack = []; 01Stack.push("a"); 02Stack.push("b"); 03 04console.log(Stack); // ["a", "b"] 05 06var temp = Stack.pop(); 07console.log(temp); // b 08console.log(Stack); // ["a"]
# 队列 ↵
同时使用
unshift
pop
或者 shift
push
可以实现队列的入队出队操作。00var Queue = ["a", "b"]; 01Queue.push("c"); 02console.log(Queue); // ["a", "b", "c"] 03 04var head = Queue.shift(); 05var tail = Queue.pop(); 06console.log(head); // "a" 07console.log(tail); // "c" 08console.log(Queue); // ["b"] 09 10Queue.unshift("x"); 11console.log(Queue); // ["x", "b"]
# 裂项 合并 ↵
# 分割数组
array.slice(from, to)
- splice会创建并返回一个新数组,这个数组是原数组array的一个子集,从下标from开始到下标to结束(不包括to下标)。
- from 和 to 可以使用负数表示
倒数
- 再次声明,slice不会改变原数组
00var a = [0, 1, 2, 3, 4, 5, 6, 7]; 01a.slice(3); // return [3, 4, 5, 6, 7] 02a.slice(0, 3); // return [0, 1, 2] 03a.slice(0, -2); // return [0, 1, 2, 3, 4, 5] 04a.slice(-2); // return [6, 7] 05a.slice(-3, -2);// return [5]
array.splice(index,howmany,item1,…,itemX)`
- index是添加/删除项目的位置,使用负数可从数组结尾处指定位置
- 要删除的项目数量,如果设置为 0,则不会删除项目。
- 注意,splice会改变原数组
00var a = [0, 1, 2, 3, 4, 5, 6, 7]; 01a.splice(4); // reutrn [4, 5, 6, 7] 02a; // now a is [0, 1, 2, 3] 03 04a = [0, 1, 2, 3, 4, 5, 6, 7]; 05a.splice(2, 5); // return [2, 3, 4, 5, 6] 06a; // now a is [0, 1, 7] 07 08// insert value to array 09a = [0, 1, 2, 3, 4, 5, 6, 7]; 10a.splice(2, 0, 'A'); // return [] 11a; // [0, 1, 'A', 2, 3, 4, 5, 6, 7]; 12 13// replace an item in array 14a = [0, 1, 2, 3, 4, 5, 6, 7]; 15a.splice(2, 1, 'A'); // return [2] 16a; // [0, 1, 'A', 3, 4, 5, 6, 7]
# 合并数组
00var a = [1, 2, 3]; 01a.join(); // "1,2,3" 02a.join(' '); // "1 2 3" 03a.join(''); // "123"
# 排序 ↵
可以简单的调用
sort
方法排序00var values = [1, 2, 3, 4, 5]; 01values.sort(); 02console.log(values); // [5, 4, 3, 2, 1]
sort方法对数值的排序比较好,但是如果要排序对象,怕是不行了,因此sort提供了回调来完成这方面的排序
00var personA = { 01 age: 16 02} 03var personB = { 04 age: 23 05} 06var personC = { 07 age: 20 08} 09var persons = [personA, personB, personC]; 10persons.sort(); // also [personA, personB, personC] 11persons.sort(function(a, b){ 12 if (a.age < b.age){ 13 return -1; 14 } else if (a.age == b.age){ 15 return 0; 16 } else { 17 return 1; 18 } 19}); 20console.log(persons); // [personA, personC, personB]
任何排序都需要这样的函数:使得其比较运算
f(a, b)
的结果在 {-1, 0, 1}
上取值,可以认为a b组成的集合G
所构成代数系统
的某种运算x:<G, x>
任何排序都需要构造这样的映射f, 使得
可以认为a b组成的
f(a, b)
值域为形如 {-1, 0, 1}
的集合。可以认为a b组成的
集合G
所构成代数系统
的某种运算x:<G, x>
# 位标 ↵
js的数组下标是从 0 开始的
00var numbers = [1, 2, 3, 4, 5, 4]; 01console.log(numbers.indexOf(4)); // 3 02console.log(numbers.lastIndexOf(4)); // 5 03 04// 如果数组里没有这个元素会返回 -1 而不是 false 或 undefined 之流 05console.log(numbers.indexOf("ooooops!")); // -1
# 迭代 ↵
数组迭代方法
- every(cb): 对每一项执行cb回调函数,全部返回true的时候返回true
- filter(cb): 对每一项执行cb回调函数,返回true项构成的新数组返回
- forEach(cb): 对每一项执行cb回调函数
- map(cb): 对每一项执行cb回调函数,返回值组成新数组返回
- some(cb): 对每一项执行cb回调函数,只要有一个返回true 就返回true
00var values = [1, 2, 3, 4, 5]; 01 02// 回调参数 elem index array 指的是 当前迭代项 下标 数组本身 03// 对于任意数组项,如果都是正数,则返回true 否则返回false 04var every_result_true = values.every(function(elem, index, array){ 05 if (elem >= 0){ 06 return true; 07 } 08}); // every_result_true is true 09 10// 对于任意数组项,如果都大于3,则返回true 否则返回false 11var every_result_normal = values.every(function(elem, index, array){ 12 if (elem > 3){ 13 return true; 14 } else { 15 return false; 16 } 17}); // every_result_normal is false 18 19var filter_result = values.filter(function(elem, index, array){ 20 if (elem > 3){ 21 return true; 22 } else { 23 return false; 24 } 25}); // filter_result is [4, 5] 26 27var forEach_result = values.forEach(function(elem, index, array){ 28 return elem; 29}); // forEach_result is undefined 30 31var map_result = values.map(function(elem, index, array){ 32 if (elem > 3){ 33 return elem+"这一项比3大"; 34 } else { 35 return elem+"这一项不大于3"; 36 } 37}); // map_result is ['1这一项不大于3', '2这一项不大于3', '3这一项不大于3', '4这一项比3大', '5这一项比3大'] 38 39// 如果数组存在大于3的项 则返回true 否则返回false 40var some_result_true = values.some(function(elem, index, array){ 41 if (elem > 3) { 42 return true; 43 } else { 44 return false; 45 } 46}); // some_result_true is true 47 48// 如果数组里存在项的值是 'oooops!' 则返回true 否则返回false 49var some_result_normal = values.some(function(elem, index, array){ 50 if (elem == 'oooops!') { 51 return true; 52 } else { 53 return false; 54 } 55}); // some_result_normal is fasle 56 57console.log(every_result_true); 58console.log(every_result_normal); 59console.log(filter_result); 60console.log(forEach_result); 61console.log(map_result); 62console.log(some_result_true); 63console.log(some_result_normal);

result
# 归并 ↵
初始值
下面的求和就很好的表示了这个过程
prev
在不断迭代元素的时候逐渐接近结果下面的求和就很好的表示了这个过程
00// reduce 01var values = [1, 2, 3, 4, 5]; 02console.log(values); 03var sum = values.reduce(function(prev, cur, index, array){ 04 console.log(prev); // 1 3 6 10 05 return prev + cur; 06}); 07console.log("sum: " + sum); // 15 08 09// reduceRight 10var values02 = [1, 2, 3, 4, 5]; 11console.log(values02); 12var sum = values02.reduceRight(function(prev, cur, index, array){ 13 console.log(prev); // 5 9 12 14 14 return prev + cur; 15}); 16 17// 15 18console.log("sum: " + sum);
# 灵活的数组 ↵
JS数组提供了很多接口,编程的时候要额外注意,避免重复造轮子。
遍历模式不只有
for循环
,还可以用回调的方式遍历,这是JS的特性。
SQ
队列栈
- push pop
- 对末项的操作
- shift unshift
- 对首项的操作
割补
- splice
- 替换
splice(where, 1, value)
- 插入
splice(where, 0, value)
- slice
- 返回start到end的一段拷贝
slice(start, end)
- 不包括 end
- join
- 用sep合并数组项
join(sep)
- 无参时默认用
','
合并
回调
- 遍历
(elem, index, array) => {};
every
some
公共属性 特征属性
filter
有条件过滤
map
有条件替换
forEach
回调遍历
- 排序
(a, b) => {};
- 关键是做
映射f
到集合E: {-1, 0, 1}
- 归并
(prev, cur, index, array) => {};
- 如前面所述初始值 prev 在不断迭代元素的时候逐渐接近结果