JavaScript语言精粹-笔记4-数组
数组(Array)的定义
- C实现的数组: 数组是一段线性分配的内存, 它通过整数计算偏移并访问其中的元素, 是一种性能出色的数据结构.
- JavaScript的数组是伪数组, 是一种拥有一些类数组(array-like)特性的对象.
- JavaScript将真数组的下标转换成字符串, 用其做为属性.
数组字面量(Array Literals)
通过数组字面量来创建数组, 继承自Array.prototype
// 创建数组字面量
var numbers = [ 'zero', 'one', 'two', 'three' ];
// 由于组数实质是一个特殊的对象, 因此可以往numbers增加其它属性
numbers.hello = true;
// 使用Object.keys查看numbers的所有属性名
// 我们可以把数组的下标称为整数属性
console.log(Object.keys(numbers)); // [ '0', '1', '2', '3', 'hello' ]
长度(Length)
每个数组都有一个length属性, JavaScript数组的length是没有上界的, 如果用大于或等于当前length的数字作为下标来存储一个元素, 那么length属性的值是这个下标值(数组的最大整数属性名)加1, 示例:
// 接数组字面量示例定义的numbers
console.log(numbers.length); // 4
numbers[9] = 'nine';
console.log(numbers.length); // 10
console.log(numbers); // [ 'zero', 'one', 'two', 'three', <5 empty items>, 'nine', hello: true ]
- length的最大值为
4294967295
, 因此数组下标的最大值是length - 1
即4294967294
, 其中数字4294967295
是2的32次方减1.
// 接上一示例的numbers
numbers[4294967295] = 'max + 1';
console.log(numbers.length); // 10
numbers[4294967294] = 'max';
console.log(numbers.length); // 4294967295
console.log(numbers); // [ 'zero', 'one', 'two', 'three', <5 empty items>, 'nine', <4294967284 empty items>, 'max', hello: true, '4294967295': 'max + 1' ]
- length的值是可以直接修改的, 设置更大的length不会给数组分配更多的内存, 而把length设小将导致所有下标大于等于新length的属性被删除, 示例:
// 接上一示例的numbers
numbers.length = 9;
console.log(numbers); // [ 'zero', 'one', 'two', 'three', <5 empty items>, hello: true, '4294967295': 'max + 1' ]
numbers.length = 11;
console.log(numbers); // [ 'zero', 'one', 'two', 'three', <7 empty items>, hello: true, '4294967295': 'max + 1' ]
numbers.push('test');
console.log(numbers); // [ 'zero', 'one', 'two', 'three', <7 empty items>, 'test', hello: true, '4294967295': 'max + 1' ]
删除(Delete)
由于JavaScript的数组其实就是对象, 所以delete运算符可以在数组中使用. 但delete会在对应下标处留下empty引用, length并没有变化, 这明显是不合理的, 我们可以用数组的splice方法移除元素, 示例:
var numbers = [ 'zero', 'one', 'two', 'three' ];
delete numbers[2];
console.log(numbers); // [ 'zero', 'one', <1 empty item>, 'three' ]
numbers.splice(2, 1);
console.log(numbers); // [ 'zero', 'one', 'three' ]
枚举(Enumeration)
因为JavaScript的数组其实就是对象, 所以我们可以使用for in
语句来遍历一个数组的所有属性, 但这种方法无法保证顺序且原型链继承来的属性也会被遍历出来, 所以for in
语句一般不会应用在数组枚举上.
我们可以使用for语句加length值来枚举数组.
容易混淆的地方(Confusion)
由于JavaScript的数组就是一种特殊的对象, 导致typeof运算符返回数组的类型是object
, 我们可能会使用这种方法来判断是数组还是对象:
var is_array = function (value) {
return value &&
typeof value === 'object' &&
value.constructor === Array;
}
上面的方法在一般情况下是可以生效的, 但是如果数组的产生是继承自其它类数组对象来的, 那么value.constructor === Array
语句判断就会失效, 有一种更好的方式去判断一个对象是否为数组:
var is_array = function (value) {
return Object.prototype.toString.apply(value) === '[object Array]';
}
方法(Methods)
JavaScript提供了一套数组可用的方法. 这些方法是被存储在Array.prototype
中的函数, Array.prototype
和Object.prototype
一样可以被扩充.
JavaScript数组是种特殊的对象, 和对象的区别除了它那些特殊的方法外就是那个非常奇妙的length属性, 如果对数组使用Object.create
并不能创建一个继承原数组的数组, 因为Object.create
产生的是对象, 这个对象继承了数组的值和方法, 但它没有那个特殊的length属性.
指定初始值(Dimensions)
书中自定义了dim和matrix两个方法来生成指定初始值的数组, 一般情况下博主会用new Array(num).fill(val)
的方式来生成指定初始值的数组.