02 September 2013
JS,数组,伪数组与对象
我们都知道,数组与对象非常的相似,但它们还是有区别的。
虽然在JS中任何变量都是对象,(除了null和undefined),但是Array对象有它自己的特性:
- 它从
Array.prototype
中继承了一些它的专属方法,如push()
,pop()
,sort()
,slice()
,splice()
等,这些方法在Object对象中是没有的。 - 它有属性length,等
好了,下面我们来看看一些伪数组(Array-like Object),比较典型的就是 function.arguments
与HTML中的 NodeList
。
我们通过查看arguments与nodeList对象,可以看到它里面有length属性,但是它并不是数组!
如:
var node_list = document.getElementsByTagName(‘div’);
node_list.length = xx;
typeof node_list ; // “object"
node_list.join(‘,’); //Object xxx has no method “join” 它不是一个数组!
好吧,虽然这让人很不爽,但是我们有新的办法!
我们知道 Array.prototype
中有个 slice(start,end)
方法,它返回数组中从start开始,end结束(不包括)的元素组成的数组。
我们可以这样调用它,
var node_array = Array.prototype.slice.call(node_list);
好了!现在node_array就是一个真正的数组了!
node_array.join(‘,’); // "[object HTMLDivElement],[object HTMLDivElement],[object HTMLDivElement]…”;
问题:
在神奇的IE中, NodeList
并不是一个JS对象。所以我们并不能使用 Array.prototype.slice.call()
来调用它。
这个时候我们只能用土办法,for循环遍历它并push进新数组。
我们可以这样写:
function make_real_array(obj) {
var arr = [];
try {
arr = Array.prototype.slice.call(obj);
return arr;
}
catch (e) {
var length = obj.length;
if (!length) return false;
for (var i = 0; i < length; i++) {
arr.push(obj[i]);
}
return arr;
}
}
另外从参考文章中看到的高级方法:将要转换的数组用一个对象包装
var ArrayContainer = function (arr) { //数组包装对象
this.arr = arr || [];
this.length = this.arr.length;
};
ArrayContainer.prototype.add = function (item) { //添加add方法
index = this.arr.length;
this.arr[index] = item;
this.length = this.arr.length;
return index;
};
ArrayContainer.prototype.get = function (index) { //添加get方法
return this.arr[index];
};
ArrayContainer.prototype.forEach = function (fn) { //遍历,传入一个function,function可以接收3个参数,i,arr[i],arr
if (this.arr.forEach) this.arr.forEach(fn); // use native code if it's there
else {
for (i in this.arr) {
fn(i, this.arr[i], this.arr);
}
}
};
调用:
var nodelist = document.getElementsByTagName('div');
var array = new ArrayContainer(nodelist);
array.forEach(function (i, v) {
console.log(‘index’ + i + 'value' + v)
});
虽然效率没有第一种方法高,但是更为可靠。我们可以在特殊需要的时候使用下面一种方法。
参考文章地址:http://nfriedly.com/techblog/2009/06/advanced-javascript-objects-arrays-and-array-like-objects/
Posted in 2013-09-02 16:07