一、数据结构
在JavaScript中常见的数据结构分为原始类型(Boolean、String、undefined、null)和引用类型(Object)。引用类型里细分又可分为Array、Function、Date等。对象和数组Array的区别在于:对象使用命名索引(即key,key-value对中的key类型为string),而数组是特殊类型的对象其使用数字索引。如果希望元素名为字符串(文本),则应使用对象;如果希望元素名为数字,则应使用数组。
我们平时经常见到的类数组对象(伪数组)实质上属于对象,但并非Array。伪数组具备两个特征:(1)按索引方式储存数据;(2)具有length属性。但它只是在特性上像数组,而不具备数组从Array.prototype中继承的方法(尽管如此,可以间接地使用Function.call方法调用,如[].slice.call(arguments))。并且数组具有其他对象所没有的特性:1)当有新的元素添加到列表时,自动更新length属性;2)设置length为一个较小值将截断数组。
那如何识别数组呢?
(1)ES3方法:instanceof运算符;
(2)ES5方法:Array.isArray()
(3)自定义函数:利用constructor属性
var fruits = ['apple', 'banana', 'orange']
fruits instanceof Array // true
Array.isArray(fruits) // true
function isArrayIf(x) {
return x.constructor.toString().indexOf("Array") > -1
}
isArrayIf(fruits) // true
遍历方式总结:

二、遍历方式
2.1 for循环
处理数据类型为:数组和伪数组(因为这个方法要求有length属性及下标,只有Array和伪数组有)。
支持break、continue方式跳出循环;


不支持return方式跳出循环,会抛出异常;

2.2 forEach()
为数组中的每个元素执行一次回调函数。不需要通过索引去访问数组项。
不支持break、continue,它会抛出异常;


不能return从函数体返回;

指定的返回值无效,返回值为undefined

2.3 map()
创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
// 下面的代码创建了一个新数组,值为原数组中对应数字的平方根。
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt); // roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9]
// 以下代码使用一个包含对象的数组来重新创建一个格式化后的数组。
var kvArray = [{key: 1, value: 10}, {key: 2, value: 20}, {key: 3, value: 30}];
var reformattedArray = kvArray.map(function(obj) {
var rObj = {};
rObj[obj.key] = obj.value;
return rObj;
});
// reformattedArray 数组为: [{1: 10}, {2: 20}, {3: 30}],
// kvArray 数组未被修改: [{key: 1, value: 10}, {key: 2, value: 20}, {key: 3, value: 30}]
不支持break和continue跳出,map()会抛出异常:

不能return从函数体返回,中途return则该轮项目为undefined。

不显示指定函数return值,return值则为与该数组长度相等的数组其内元素均为undefined:

注意:map()方法内的回调函数内的操作一定不能直接在原项目上直接赋值,否则会出现引用类型指针不变导致的原数组被篡改的问题

改用新建变量拷贝的方法才能避免上述问题:

2.4 for in 遍历
Thefor...in
语句遍历一个对象的所有可枚举属性(enumerable properties ),这些属性的键名为字符串(会忽略掉键名为Symbol的),包括自身和继承自原型的可枚举属性。
是为object设计的,虽然能遍历数组但有瑕疵(如果 array 有自定义属性也会被遍历出来);


支持break/ continue跳出循环,


不支持return跳出,for in会报异常:

2.5 for of 遍历
for...of
语句创建一个循环,循环访问可迭代对象,这些对象包括:内置String,Array,类似数组的对象(例如,arguments或NodeList
),TypedArray,Map,Set和用户定义的可迭代对象。
var iterable = [10, 20, 30];
for (var value of iterable) {
value += 1;
console.log(value);
}
// 11
// 21
// 31

支持breakcontinue跳出循环:


不支持return跳出循环:

2.6 Object.keys()
Object.keys()
方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用for...in
循环遍历该对象时返回的顺序一致 。若想获取一个对象的所有属性甚至包括不可枚举的则Object.getOwnPropertyNames
。

2.7 Object.values()
Object.values()
方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in
循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。

2.8 Object.entries()
Object.entries()
方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用for...in
循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。

2.9 Object.getOwnPropertyNames()
Object.getOwnPropertyNames()
方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。Object.getOwnPropertyNames()
返回一个数组,该数组对元素是obj
自身拥有的枚举或不可枚举属性名称字符串。 数组中枚举属性的顺序与通过for...in
循环(或Object.keys
)迭代该对象属性时一致。数组中不可枚举属性的顺序未定义。


本文引用参考:
JavaScript权威指南(第6版)book.douban.com 实战课程_开发项目实战_编程项目实战-慕课网coding.imooc.com
