说明
数组的长度是可变,不像java中,要先定义数组的长度
创建方式
字面量方式
var cars = [“Saab”, “Volvo”, “BMW”]; 指定数组长度 var arr= []; arr.length = 100;
构造函数方式
var cars = new Array(“宝马”,“奔驰”,“奥迪”); 指定数组长度 var arr = new Array(5); 数组长度为5 【注意】 var arr = new Array(1,2); 就是[1,2]了,只有当构造函数接受一个参数的时候是指定数组长度
两种方式没有差别,最好不要使用构造函数的方式, 因为会对内存有影响;???为啥 Array作为构造函数,行为很不一致。因此,不建议使用它生成新数组,直接使用数组字面量是更好的做法。
Array.from() 将伪数组变成数组,就是只要有length的属性就可以转成数组
let name = "javascript";console.log(name.length); // 10let arr = Array.from(name);console.log(arr); // [ 'j', 'a', 'v', 'a', 's', 'c', 'r', 'i', 'p', 't' ]
复制代码
Array.of() 将一组值转换成数组,类似于声明数组
let arr = Array.of(10);let arr2 = Array.of("hello", "world");console.log(arr); // [ 10 ] console.log(arr2); // [ 'hello', 'world' ]
复制代码
类型判断
Array.isArray()
注意Array.isArray(arr) 不兼容ie6-ie8 不改变原数组 参数:目标数组 返回:【Boolean】是数组:true 不是数组:false
typeof
不能判断是否是数组
let arr = []console.log(typeof arr); // object
复制代码
instanceof
let arr = []console.log(arr instanceof Array);// true
复制代码
获取数组长度length
var length= arr.length;
转换为字符串toString()&join()
toString()
内容按逗号分隔
var fruits = ["Banana", "Orange", "Apple", "Mango"];document.getElementById("demo").innerHTML = fruits.toString();// 结果 Banana,Orange,Apple,Mango
let arr = [];arr[0] = {hah:123}arr[1] = {dada:234}console.log(arr)console.log(arr.toString());// [ { hah: 123 }, { dada: 234 } ]// [object Object],[object Object]
复制代码
valueOf()
方法返回数组本身
var a = [1, 2, 3];let res = a.valueOf() console.log(res);// [1, 2, 3]console.log(Array.isArray(res));// true
复制代码
join()
作用:可以设置内容分隔的符号 参数:【String】 返回:【String】
var fruits = ["Banana", "Orange","Apple", "Mango"];document.getElementById("demo").innerHTML = fruits.join(" * "); 结果:Banana * Orange * Apple * Mango如果数组内为对象,输出结果也和toString的效果一样var fruits = ["Banana", "Orange","Apple", "Mango"];console.log(fruits.join('$$$$'));//Banana$$$$Orange$$$$Apple$$$$Mango
复制代码
数组的遍历、迭代
forEach();
参数:function(currentValue,index,arr){} 注意: 1.通过val不能修改,通过arr[index]赋值可以改变源数组项 2.如果数组中有空位(注意不是undefineddefined),会自动过滤不执行改次方法体,但是索引还是会叠加。
修改每一个val,不会改变原来的数组,要用arr[index]来处理 val是不能被改变的,但是val(如果是对象的话)中的内容是可以被改变的
var arr = [23, 9, 4,undefined, 78, 3];arr.forEach(function(val,index,arr){ console.log(val); // 这里是会打印undefined});
复制代码
使用try catch跳出forEach循环,不得已而为
function getItemById(arr, id) { var item = null; try { arr.forEach(function (curItem, i) { if (curItem.id == id) { item = curItem; throw Error(); } }) } catch (e) { } return item; }
复制代码
3.1 foreach()不能使用break和continue这两个关键字,foreach和普通的for循环是不同的,它不是普通的遍历,实现continue的效果可以直接使用return。forEach使用return是不能结束循环的,可以使用try catch封装一个函数。 3.2 forEach的优势一个是它的回调函数形成了一个作用域,它的curItem和i不会像for循环一样污染全局变量,再一个是更容易写出来函数式的代码,和map、filter、reduce这些高阶函数是一脉相承的,这些函数也不能直接跳出循环。 3.3 forEach()本身无法跳出循环,必须遍历所有的数据才能结束。
for…in 循环和数组的遍历
for…in循环不仅可以遍历对象,也可以遍历数组,毕竟数组只是一种特殊对象。 不推荐使用for…in遍历数组,因为会遍历非数字键。
var a = [1, 2, 3];for (var i in a) { console.log(a[i]);}// 1// 2// 3但是,for...in不仅会遍历数组所有的数字键,还会遍历非数字键。var a = [1, 2, 3];a.foo = true;for (var key in a) { console.log(key);}// 0// 1// 2// foo
复制代码
map()
默认不改变源组 参数:function(currentValue,index,arr), thisValue){} 作用:处理数组每一项,方法按照原始数组元素顺序依次处理元素 返回:一个处理后的新数组,数组中的元素为原始数组元素调用函数处理后的值。
注意: map() 不会对空数组进行检测。 注意: map() 不会改变原始数组。
var arr = [23, 9, 4,22, 78, 3];let res = arr.map(function(val,index,arr){ return val*10});console.log(res);// [ 230, 90, 40, 220, 780, 30 ]console.log(arr);// [ 23, 9, 4, 22, 78, 3 ]
复制代码
**
filter()
作用:过滤数组,满足返回条件的数据 对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。
let arr = [1, 2, 3, 4, 5, 6];// 取数组中大于3的值重新组成新数组let newArr = arr.filter(value => value > 3);console.log(newArr); // [ 4, 5, 6 ]
复制代码
** **
every()
对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
let arr = [1, 2, 3, 4, 5, 6];// 是否所有的值都大于3let isTrue = arr.every(value => value > 3);console.log(isTrue); // false;
复制代码
some()
参数:function(currentValue,index,arr), thisValue){} 对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。 注意:
-
some函数的return不会退出外层函数
-
空数组不会报错,结果是false
-
currentValue的改变不会改变原数组中的值
let arr = [1, 2, 3, 4, 5, 6];// 迭代数组的每一项,只要有一项符合条件就返回truelet isTrue = arr.some(val => val >= 5);let isTrue2 = arr.some(val => val > 6);console.log(isTrue); // trueconsole.log(isTrue2); // false
reduce()和reduceRight()
这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。其中,reduce()方法从数组的第一项开始,逐个遍历到最后。而reduceRight()则从数组的最后一项开始,向前遍历到第一项。
let arr = [1, 2, 3, 4];// 从左到右累加结果let result = arr.reduce((val1, val2) => { return val1 + val2;});console.log(result); // 10
复制代码
**
entries(),keys() 和 values()
ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象,可以用for…of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。
let arr = [1, 2, 3];// entries()是对键值对的遍历for (let val of arr.entries()) { console.log(val); /** [ 0, 1 ] [ 1, 2 ] [ 2, 3 ] */}// keys()是对键名的遍历for (let val of arr.keys()) { console.log(val); // 0 1 2}// values()是对键值的遍历for (let val of arr.values()) { console.log(val); // 1 2 3}
复制代码
find()
参数:【Function(val,index,arr)】 接受:数组值,数组循环当前的索引,源数组 返回:return为true时的数组值 注意:满足为true条件会中断循环,通过val不能赋值,通过arr[index]赋值可以改变源数组。 数组实例的find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
let arr = [1, 2, 3, 4, 5, 6];let value = arr.find(val => val === 3);let value2 = arr.find(val => val === 100);console.log(value); // 3console.log(value2); // undefined
复制代码
如果find直接给的true 返回的就是数组的第一项
findIndex()
和数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
let arr = [1, 2, 3, 4, 5, 6];let index = arr.findIndex(val => val === 3);let index2 = arr.findIndex(val => val === 100);console.log(index); // 2console.log(index2); // -1
复制代码
排序 reverse()&sort()
arr.reverse()
反转数组顺序 参数:无 返回:源数组的倒序
arr.sort()
改变源数组顺序 定义:按ASCII或大小值排序 参数:一个函数, 接受两个参数, 返回Number类型才有效,不然还是源数组
返回:改变后的源数组 函数有两个参数,分别代表第一个值和第二个值 一般我们使用sort函数进行数组的排序,sort()方法有一个可选参数,是用来确定元素顺序的函数。如果这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序。 其实,sort方法会调用每个数组项的toString()方法,得到字符串,然后再对得到的字符串进行排序。虽然数值15比3大 如:
var arr = ["a", "b", "A", "B"];arr.sort();console.log(arr);//["A", "B", "a", "b"]// 默认排序是ASCII排序var arr = ["1", "2", "3", "121"];arr.sort();console.log(arr);// [ '1', '121', '2', '3' ] 因为这里是按ASCII码排序的var arr = [15, 8, 25, 3];arr.sort();console.log(arr);//[15, 25, 3, 8] // 这也是因为是按ASCII码排序的// 返回的就是源数组的引用var arr = [23, 9, 4, 78, 3];let res = arr.sort(function(a,b){ return b-a});console.log(res); // [78,23,9,4,3]console.log(arr); // [78,23,9,4,3]console.log(arr === res); // true
复制代码
sort()方法的参数就起到了作用,我们把这个参数叫做比较函数。比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回0,如果第一个参数应该位于第二个之后则返回一个正数。 a,b表示数组中的任意两个元素,若return > 0 b前a后;reutrn < 0 a前b后;a=b时存在浏览器兼容。a-b输出从小到大排序,b-a输出从大到小排序 例子:
var arr = [23, 9, 4, 78, 3];arr.sort(function(a,b){ return b-a;});console.log(arr); // [78,23,9,4,3]
复制代码
数组的排序有很多种,详见dfWeb代码
添加数组元素 push()&unshift()
arr.push();
作用:向数组末尾添加元素 改变源数组 参数:将要添加进入源数组的数值,可以是一个值,也可以是多个值,也是可以是数组,也可以组合。 如果不写参数的话,返回源数组长度,但是不会改变源数组。 返回:改变后的数组的长度
var fruits = ["Banana", "Orange", "Apple", "Mango"];var x = fruits.push("Kiwi"); // x 的值是 5, 改变后的长度var x = fruits.push(["Kiwi",'小丁'],'小锋'); //这样都是可以的
复制代码
相当于arr[arr.length] = “玛莎拉蒂”; 注意上面这种方式可以任意指定索引, 数组会自动补充长度,中间如果有未定义的,
arr.unshift()
改变源数组 定义:向数组前面(在开头)添加新元素,并“向后位移”旧元素 参数:将要添加进入源数组的数值,多个值,或数组,同push()方法 返回:改变后数组的长度
var fruits = ["Banana", "Orange", "Apple", "Mango"];fruits.unshift("Lemon"); // 返回 5 改变后数组的长度var fruits = ["Banana", "Orange", "Apple", "Mango"];var a = fruits.unshift("Lemon","小明");console.log(fruits) // Lemon,小明,Banana,Orange,Apple,Mangoconsole.log(a) // 6var a = fruits.unshift(["Lemon","小明"]); 参数是数组也是可以的var a = fruits.unshift(["Lemon","小明",'gou'],'mao'); 这样也是可以的
复制代码
设置arr.lenth也可以向末尾添加元素或则删除元素
删除数组元素 pop()&shift()&delete
pop()
改变源数组 作用:从数组中删除最后一个元素 参数:无,带了也无用 返回: 返回被删除的值。 注意:如何是空数组,返回undefined,不改变源数组
var fruits = ["Banana", "Orange", "Apple", "Mango"];var x = fruits.pop(); // x 的值是 "Mango"// 如果是空数组let arr = []let res = arr.pop()console.log(res); // undefinedconsole.log(arr); // []
复制代码
shift()
改变源数组 作用:从数组中删除第一个元素,位移与弹出等同,但处理首个元素而不是最后一个。 参数:无,带了也无用 返回:被“位移出”删除的字符串。改变源数组 方法会删除首个数组元素,并把所有其他元素“位移”到更低的索引
var fruits = ["Banana", "Orange", "Apple", "Mango"];fruits.shift(); // 返回 "Banana"// 如果是空数组let arr = [] let res = arr.pop()console.log(res); // undefinedconsole.log(arr); // []
复制代码
delete
改变源数组 作用:将数组某个元素变成undefined,并且不会影响length属性 既然 JavaScript 数组属于对象,其中的元素就可以使用 JavaScript delete 运算符来删除: 使用 delete 会在数组留下未定义的空洞。请使用 pop() 或 shift() 取而代之。 参数:无 返回:无
var fruits = ["Banana", "Orange", "Apple", "Mango"];delete fruits[0]; // 把 fruits 中的首个元素改为 undefined
复制代码
注:delete也可以操作对象,详细见js_Obejct篇幅。 delete只会作用在实例上,而不会作用在原型上。
插入、删除、替换 splice()
splice()
改变源数组 参数: 在使用时特别注意第一个和第二个参数的范围。 第一个参数: Number (2)定义了应添加新元素的索引位置(拼接)。 如果该参数大于源数组长度,则无论第二个参数是多少,作用相当于 在源数组后面追加元素。返回[]
第二个参数: Number(0)定义应删除原来数组多少元素。【代码选填,效果必填】 不填的话 表示一直到数组末尾,相当于arr.length-第一个参数。 如果超过剩余的元素个数,不会报错,自动到数组末尾。 其余参数:(“Lemon”,“Kiwi”)定义要添加的新元素。【选填】 插入数组的话 并不会自动扩展开来 返回:【Array】被删除的部分
使用splice() 来插入元素 改变源数组 方法向数组添加新元素,并返回包含已删除元素(如果有)的数组, 并且改变老数组。 相当于插入的功能
eg:1 在索引2的位置插入多个值var fruits = ["Banana", "Orange", "Apple", "Mango"];var a = fruits.splice(2, 0, "小明", "小红");console.log(fruits);console.log(a);// 输出[ 'Banana', 'Orange', '小明', '小红', 'Apple', 'Mango' ][]eg:2 在索引2的位置往后一位替换多个值var fruits = ["Banana", "Orange", "Apple", "Mango"];var a = fruits.splice(2, 1, "小明", "小红");console.log(fruits);console.log(a);// 输出[ 'Banana', 'Orange', '小明', '小红', 'Mango' ][ 'Apple' ]eg:3 在索引2的位置插入一个数组值var fruitsB = ["Banana", "Orange", "Apple", "Mango"];var b = fruitsB.splice(2, 0, ["小明", "小红"]); // 参数并不会自动展开console.log(fruitsB);console.log(b);// 输出[ 'Banana', 'Orange', [ '小明', '小红' ], 'Apple', 'Mango' ][]
复制代码
使用 splice() 来删除元素 第三个参数不填 改变源数组 通过聪明的参数设定,您能够使用 splice() 在数组中不留“空洞”的情况下移除元素:
eg:删除指定索引后的多少个元素var fruits = ["Banana", "Orange", "Apple", "Mango"];var a = fruits.splice(0, 1); // 删除 fruits 中的第一个元素console.log(fruits);console.log(a);// [ 'Orange', 'Apple', 'Mango' ]//[ 'Banana' ]eg: 2 删除指定索引后的所有元素var fruits = ["Banana", "Orange", "Apple", "Mango"];var a = fruits.splice(0);console.log(fruits);console.log(a);// 输出[][ 'Banana', 'Orange', 'Apple', 'Mango' ]
复制代码
第一个参数(0)定义新元素应该被添加(接入)的位置。 第二个参数(1)定义应该删除多个元素。 其余参数被省略。没有新元素将被添加。
使用splice()l来替换元素 第二参数为1
var fruits = ["Banana", "Orange", "Apple", "Mango"];fruits.splice(1, 1,'小明'); // 删除 fruits 中的第二个元素结果:["Banana", "小明", "Apple", "Mango"];
复制代码
截取数组 slice()
slice()
不改变源数组 作用: 截取数组项 slice() 方法创建新数组。它不会从源数组中删除任何元素。 方法用数组的某个片段切出新数组。返回被切出部分,一个数组,不改变老数组 参数: 第一个参数: 【Number】 索引 第二个参数:【Number】索引 从哪到哪 前包括后不包括,第二个参数不填自动定位末尾 返回:【Array】 源数组被截取的分
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];var citrus = fruits.slice(3); // Apple,Mango本例从数组元素索引 3("Apple")开始指导末尾切出一段数组:var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];var citrus = fruits.slice(1, 3); // Orange,Lemon当给 slice() 方法赋予两个参数时,它从 start 参数中选择数组元素,直到(但不包括)end 参数
复制代码
拼接数组 concat()
concat()
不改变源数组,会返回一个新数组 参数:Any,多个;值、数组 返回:Array 合并后的新数组 方法通过合并(连接)现有数组来创建一个新数组,并且总是在末尾处连接
concat() 方法可以使用任意数量的数组参数:
var arr1 = ["Cecilie", "Lone"];var arr2 = ["Emil", "Tobias", "Linus"];var arr3 = ["Robin", "Morgan"];var myChildren = arr1.concat(arr2, arr3); // 将arr1、arr2 与 arr3 连接在一起// Emma,Isabella,Jacob,Michael,Ethan,Joshua,Danielvar arr1 = ["Cecilie", "Lone"];var myChildren = arr1.concat(["Emil", "Tobias", "Linus"]);// [ 'Cecilie', 'Lone', 'Emil', 'Tobias', 'Linus' ]方法也可以将值作为参数:let arr = [1,2,3]let arrNew = arr.concat(123,456)console.log(arr)console.log(arrNew)//[ 1, 2, 3 ] [ 1, 2, 3, 123, 456 ]
复制代码
位置索引,判断数组是否有某值
indexOf()和lastIndexOf()
参数:这两个方法都接收两个参数:要查找的项和查找起点位置(可选的)表示的索引。其中,indexOf()
方法从数组的开头(位置0)开始向后查找,lastIndexOf()
方法则从数组的末尾开始向前查找。 返回:第一次找到元素的索引,找不到返回【Number】-1
let arr = [1, 2, 3, 2, 1];// 从0开始查询值为2的位置console.log(arr.indexOf(2)); // 1// 从索引为2开始查询值为2的位置console.log(arr.indexOf(2, 2)); // 3// 倒叙查询值为2的位置console.log(arr.lastIndexOf(2)); // 3// 倒叙查询值为2的位置console.log(arr.lastIndexOf(2, 2)); // 1
复制代码
注意,如果数组中包含NaN,这两个方法不适用,即无法确定数组成员是否包含NaN
[NaN].indexOf(NaN) // -1[NaN].lastIndexOf(NaN) // -1[NaN].lastIndexOf(NaN) // -1这是因为这两个方法内部,使用严格相等运算符(===)进行比较,而NaN是唯一一个不等于自身的值。
复制代码
includes()
方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。兼容性不太好
let arr = [1, 2, 3, 4, 5, 6];console.log(arr.includes(3)); // trueconsole.log(arr.includes(100)); // false
复制代码
in
检查某个键名是否存在的运算符in,适用于对象,也适用于数组。 如果数组的某个位置是空位,in运算符返回false。 但是数组使用的方式不太一样,它是指数组的键名就是索引, 参数String会被转成number,所以在数组中也没啥用 用在对象时,注意是string类型哦,写数字的时候会自动转成string的,只是感觉不出来
const a = { hello:'1213'}console.log('hello' in a) // trueconst b = ['12','123','34']console.log(1 in b) // trueconsole.log('1' in b) // trueconsole.log('123' in b) // false
复制代码
自定义条件查找
见:find和findIndex
数组的克隆
深克隆
可以参照对象的深克隆实现
浅克隆
方法1:可以参考对象的浅克隆方法
let obj = { name: 'zhang', age: 10,}let arr = [1,2,3,obj]let arr2 = Object.assign([], arr)arr.push('hello')arr[3].name = 'feng'console.log(arr); // [ 1, 2, 3, { name: 'feng', age: 10 }, 'hello' ]console.log(arr2) // [ 1, 2, 3, { name: 'feng', age: 10 } ]
复制代码
方法2:扩展运算符(推荐)
// ... 为浅克隆 只会把第一级克隆 第2级及后面的级数 和原始对象公用相同地址 let arr1 = [10, 20, { name: 'es6' }] // 展开运算符 let arr2 = [...arr1] console.log(arr2, arr1) console.log(arr1[2] === arr2[2]) // true
复制代码
方法3:数组方法 arr.slice()或则arr.concat()
// ... 为浅克隆 只会把第一级克隆 第2级及后面的级数 和原始对象公用相同地址 let arr1 = [10, 20, { name: 'es6' }] // 展开运算符 // let arr2 = [...arr1] let arr2 = arr1.slice(0) // 这里也可以无参 // let arr2 = arr1.concat() // 这里也可以使用数组的concat console.log(arr2, arr1) console.log(arr1[2] === arr2[2]) // true
复制代码
数组总结
以上常用方法中,不改变源数组的方法有: concat slice map
栈方法,后进先出: push pop
队列方法,先进先出: shift unshift
注意点
关联数组
很多编程元素支持命名索引的数组。 具有命名索引的数组被称为关联数组(或散列)。 JavaScript 不支持命名索引的数组。 在 JavaScript 中,数组只能使用数字索引。 假如您使用命名索引,JavaScript 会把数组重定义为标准对象,但是类型还是数组。 之后,所有数组的方法和属性将产生非正确结果。
var person = [];person["firstName"] = "Bill";person["lastName"] = "Gates";person["age"] = 62;console.log(person.length); // 0console.log(person[0]); // undefinedconsole.log(typeof person); // objectconsole.log(Object.prototype.toString.call(person)); //[object Array]console.log(person); // [ firstName: 'Bill', lastName: 'Gates', age: 62 ]
复制代码
???{}对象和【】对象有区别吗 正是由于这个原因:开发中,在和后台配合的时候,可以将将没有值的为null或undefined的对象变为空数组,这样去点属性的时候就不会报错,比如 [].name 是不会报错的
数组空位与数组元素undefined
数组的空位是可以读取的,返回undefined。
var a = [,,,];console.log(a); // [ <3 empty items> ]console.log(a[0]); // undefined
复制代码
数组的某个位置是空位,与某个位置是undefined,是不一样的。空位和undefined,使用数组的forEach方法、for…in结构、以及Object.keys方法进行遍历,空位都会被跳过。 var a = [, , ,]; var a = [undefined, undefined, undefined];
var a = [1, , 1];a.length // 3上面代码表明,数组的空位不影响length属性。---------------------------------------------------------------需要注意的是,如果最后一个元素后面有逗号,并不会产生空位。也就是说,有没有这个逗号,结果都是一样的。var a = [1, 2, 3,];a.length // 3a // [1, 2, 3]---------------------------------------------------------------数组的空位是可以读取的,返回undefined。var a = [, , ,];a[1] // undefined---------------------------------------------------------------使用delete命令删除一个数组成员,会形成空位,并且不会影响length属性。var a = [1, 2, 3];delete a[1];a[1] // undefineda.length // 3---------------------------------------------------------------数组的某个位置是空位,与某个位置是undefined,是不一样的。如果是空位,使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过。var a = [, , ,];a.forEach(function (x, i) { console.log(i + '. ' + x);})// 不产生任何输出,但是索引还是存在的for (var i in a) { console.log(i);}// 不产生任何输出Object.keys(a)// []---------------------------------------------------------------如果某个位置是undefined,遍历的时候就不会被跳过。var a = [undefined, undefined, undefined];a.forEach(function (x, i) { console.log(i + '. ' + x);});// 0. undefined// 1. undefined// 2. undefinedfor (var i in a) { console.log(i);}// 0// 1// 2Object.keys(a)// ['0', '1', '2']这就是说,空位就是数组没有这个元素,所以不会被遍历到,而undefined则表示数组有这个元素,值是undefined,所以遍历不会跳过。
复制代码
优秀操作
链式调用
上面这些数组方法之中,有不少返回的还是数组,所以可以链式使用。
var users = [ {name: 'tom', email: 'tom@example.com'}, {name: 'peter', email: 'peter@example.com'}];users.map(function (user) { return user.email;}).filter(function (email) { return /^t/.test(email);}).forEach(alert);// 弹出tom@example.com
复制代码