笔记 08 JS 数组

原文地址

数组

1 数组遍历与属性

JavaScript 中数组是对象,
但是没有好的理由去使用 for in 循环 遍历数组。
相反,有一些好的理由不去使用 for in 遍历数组。

由于 for in 循环会枚举原型链上的所有属性,
唯一过滤这些属性的方式是使用 hasOwnProperty 函数,
因此会比普通的 for 循环慢上好多倍。

遍历

为了达到遍历数组的最佳性能,推荐使用经典的 for 循环。

var list = [1, 2, 3, 4, 5, ...... 100000000];
/**
 * 虽然 length 是数组的一个属性,
 * 但是在每次循环中访问它还是有性能开销。
 * 可能最新的 JavaScript 引擎在这点上做了优化,
 * 但是我们没法保证自己的代码是否运行在这些最近的引擎之上。
 *
 * 实际上,不使用缓存数组长度的方式比缓存版本要慢很多。
 */
for(var i = 0, l = list.length; i < l; i++) {
    console.log(list[i]);
}

length 属性

length 属性的
getter 方式会简单的返回数组的长度
而 setter 方式会截断数组

为 length 设置一个更小的值会截断数组
但是增大 length 属性值不会对数组产生影响

var foo = [1, 2, 3, 4, 5, 6];
foo.length = 3;
foo; // [1, 2, 3]

foo.length = 6;
foo; // [1, 2, 3]

/**
 *  在 Firebug 中查看此时 foo 的值是: [1, 2, 3, undefined, undefined, undefined] 但是这个结果并不准确,
 *  如果你在 Chrome 的控制台查看 foo 的结果,
 * 你会发现是这样的: [1, 2, 3] 因为在 JavaScript 中 undefined 是一个变量,
 * 注意是变量不是关键字,因此上面两个结果的意义是完全不相同的。
 */

// 为了验证,我们来执行下面代码,看序号 5 是否存在于 foo 中。
5 in foo; // 不管在 Firebug 或者 Chrome 都返回 false
foo[5] = undefined;
5 in foo; // 不管在 Firebug 或者 Chrome 都返回 true

2 Array 构造函数

由于 Array 的构造函数在如何处理参数时有点模棱两可
因此总是推荐使用数组的字面语法 - [] - 来创建数组

[1, 2, 3]; // 结果: [1, 2, 3]
new Array(1, 2, 3); // 结果: [1, 2, 3]

[3]; // 结果: [3]
new Array(3); // 结果: []
new Array('3') // 结果: ['3']

// 因此下面的代码将会使人很迷惑
new Array(3, 4, 5); // 结果: [3, 4, 5]
new Array(3) // 结果: [],此数组长度为 3

// 构造函数会返回一个
// length 属性被设置为此参数的空数组
var arr = new Array(3);
arr[1]; // undefined
1 in arr; // false, 数组还没有生成

// 这种[优先于设置数组长度属性]的做法
// 只在少数几种情况下有用,
// 比如需要循环字符串,
// 可以避免 for 循环的麻烦。
new Array(count + 1).join(stringToRepeat);