数组是js中重要的数据类型,在以后的开发中会经常碰到它,其实数组也是对象。
var myArray = ["a","b","c"];
var myObject = { "0": "a", "1": "b", "2": "c" };
myArray 继承自 Array.prototype,myObject继承自Object.prototype,他们都有很多有用的方法,也有很多类似,当然也有不同。
myArray[0]; // "a" ,数字0会被自动转换为字符串"0",下同
myObject[0]; // "a"
length:数组的length属性的值等于数组的最大下标的值+1,所以length不一定等于数组的属性的个数;
myArray.length; //3
数组具有length属性,对象没有。数组的length没有上界,不会产生越界错误。
如果数组的下标等于 或者超过 了数组的length呢?
myArray[4] = "e";
此时数组的长度
myArray.length; // 5
如果把数组的length值设小,将会把大于等于新length值的属性删除。
myArray.length = 2; // myArray 是 ["a","b"]
delete运算符可以从对象删除属性,同样的也可以从数组删除属性,但是被删除的下标之后的属性并不会递减,被删除的位置留下了一个空位,所以我们可以使用数组的splice方法。
枚举
for in 语句可以用来枚举对象的属性,同样适用于数组,但是存在问题:1,无序;2,从原型链中的继承属性也可能会被枚举,所以一般用for循环语句。
区分数据类型是对象还是数组
typeof myArray; // "object"
typeof myObject; // "object"
myArray instanceof Array; // true
myArray instanceof Object; //true
js中并未提供很好的机制来区分数组和对象,所以只有自己来自定义了。
var isArray = function(value) {
return value&&typeof value === "object"&&value.constructor === Array;
}
上面的函数还是存在缺陷,就是在前端从不同的window/frame构造的数组会判断失败。
我们知道:
myObject.toString(); // "[object object]"
所以如果数组应用了对象原型中的toString方法呢?
给Array.prototype 扩充一下:
Array.prototype.isArray = Object.prototype.toString;
myArray.isArray(); // "[object Array]"
所以可以这么写
var isArray = function(value) {
return Object.prototype.toString.apply(value) === "[object Array]"
}
因为数组就是对象,所以可以直接给数组增加方法
myArray.isArray = function() {
return Object.prototype.toString.apply(this) === "[object Array]"
}
myArray.isArray(); // true
注意,上面出现了三个 isArray 函数 他们是不同的。有何不同呢?