您的位置:首页 > Web前端 > JavaScript

javascript Array对象使用小结

2009-12-24 00:00 866 查看
Javascript的数组实质是对象,它把数组的下标转换成字符串,用其作为属性,因此它明显比真正的数组慢,但它可以更方便地使用。

改变自身pop,push,reverse,shift,sort,splice,unshift, 不改变自身concat,join,slice,indexOf,lastIndexOf(后两个为1.6),1.6新增的迭代器:map,filter,forEach,every,some,1.8新增reduce,reduceRight
Array 对象的方法

FF: Firefox, N: Netscape, IE: Internet Explorer
方法
描述
FF
N
IE
concat()
向数组的副本添加新的元素,返回新的数组,原数组不受影响
1
4
4

join()
把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
1
3
4

pop()
删除并返回数组的最后一个元素
1
4
5.5

push()
向数组的末尾添加一个或更多元素,并返回新的长度。
1
4
5.5

reverse()
颠倒数组中元素的顺序。
1
3
4

shift()
删除并返回数组的第一个元素
1
4
5.5

slice()
从某个已有的数组返回选定的元素
1
4
4

sort()
对数组的元素进行排序,有一个可选参数,为比较函数。
1
3
4

splice()
删除元素,并向数组添加新元素。
1
4
5.5

toSource()
代表对象的源代码
1
4
-

toString()
把数组转换为字符串,并返回结果。
1
3
4

toLocaleString()
把数组转换为本地数组,并返回结果。
1
3
4

unshift()
向数组的开头添加一个或更多元素,并返回新的长度。
1
4
6

valueOf()
返回数组对象的原始值
1
2
4
Array 对象的属性
方法
描述
FF
N
IE
index

1
3
4

input
在普通的Array中是不具备input属性的,只有在调用String对象的match()方法后返回的数组才具有input属性。它是用来存放匹配前的原字符串的内容。
1
3
4

length
设置或返回数组中元素的数目。
1
2
4我们先来看数组克隆,现在公认用concat()来克隆数组的速度最快。下面做一些测试,分别为直接遍历复制,array.slice(0)与array.concat()


var aArr = new Array(100001).join('a').split('');
var d = new Date();
var bArr = [];
for(var i = 0; i < aArr.length; i++){
bArr[i] = aArr[i];
}
alert(new Date() - d);


[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]


var aArr = new Array(100001).join('a').split('');
var d = new Date();
var bArr = aArr.slice(0);
alert(new Date() - d);


[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]


var aArr = new Array(100001).join('a').split('');
var d = new Date();
var bArr = aArr.concat();
alert(new Date() - d);


[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
判断一个变量引用的对象是否为数组。
var isArray = function(a){ 
return a && 
typeof a === 'object' && 
typeof a.length === 'number' && 
typeof a.splice === 'function' && 
!(a.propertyIsEnumerable('length')); 
}

让数组具有计算能力,这个也很常用,不要用于财会的特殊报表中。
Function.prototype.method = function(name,func){ 
this.prototype[name] = func; 
return this; 
} 
Array.method('reduce',function(fn,value){ 
for(var i=0,l=this.length;i<l;i++){ 
value = fn(this[i],value); 
} 
return value; 
});

如何使用,我们可以创建一个数字数组与相关的四则运算函数,把它们代入reduce函数中就行了
var data = [4,8,10,12,16] 
var add = function(a,b){ 
return a+b; 
} 
var mult = function(a,b){ 
return a*b; 
} 
//使用 
var sum = data.reduce(add,0) 
var product = data.reduce(mult,1);

each方法,让元素逐个执行传入的方法。JavaScript 1.6里已经实现了相应的forEach方法,但IE不支持,人们搞了个相近的each方法,在各大类库都有相应的实现。我们看一个漂亮的实现(作者为51JS的客服果果):
Array.prototype.each = function(fn){ 
for (var i=0;i <this.length;i++) 
this[i].constructor==Array? 
this[i].each(fn): 
fn.call(this[i],i); 
}; 
[1,[2,[3,[4,[5,[6,[7,[8,[9,[0]]]]]]]]]].each( 
function(){ 
return alert(this); 
});

上面这个比较强大,除了能深层遍历数组外,还能遍历类数组对象(如arguments,NodeList),对象的所有属性都会被fn方法进行调用。但是从设计模式来看,它承担职责太多了.each方法就应该是面向数组,如果是对象或类数组对象,我们应该将它们转化为数组,如JQuery的 makeArray,mootools和Prototype的$A。
var arrayize = function(iterable){ 
try{ 
return Array.prototype.slice.call(iterable); 
}catch(e){ 
var l = iterable.length || 0, array = new Array(l); 
while (l--) array[l] = iterable[l]; 
return array; 
} 
}

接着下来我们就可以实现纯数组的each函数了。
var each = function(func, array) { 
for (var i=0,l = array.length; i<l; ++i) { 
func(array[i]) 
} 
}

然后再改成一个原型方法
Array.prototype.each = function(func) { each(func,this); };

不过,如果浏览器支持javascript1.6的forEach方法,就用forEach
Array.prototype.each = function(func) { 
if(Array.prototype.forEach){ 
this.forEach(func); 
}else{ 
each(func,this); 
} 
};

用法:
[4, 5, 6].each(function(index) { alert(index + "+2 = " + (index+2)); })

火狐官网还有一个实现:
if (!Array.prototype.forEach) 
{ 
Array.prototype.forEach = function(fun /*, thisp*/) 
{ 
var len = this.length >>> 0; 
if (typeof fun != "function") 
throw new TypeError(); 
var thisp = arguments[1]; 
for (var i = 0; i < len; i++) 
{ 
if (i in this) 
fun.call(thisp, this[i], i, this); 
} 
}; 
}

让我们看一下jQuery提供的each方法的具体实现
jQuery.each(obj,fn,arg)
该方法有三个参数:进行操作的对象obj,进行操作的函数fn,函数的参数args。
让我们根据ojb对象进行讨论:
1.obj对象是数组
each方法会对数组中子元素的逐个进行fn函数调用,直至调用某个子元素返回的结果为false为止,也就是说,我们可以在提供的fn函数进行处理,使之满足一定条件后就退出each方法调用。当each方法提供了arg参数时,fn函数调用传入的参数为arg,否则为:子元素索引,子元素本身。
2.obj 对象不是数组
该方法同1的最大区别是:fn方法会被逐次不考虑返回值的进行进行。换句话说,obj对象的所有属性都会被fn方法进行调用,即使fn函数返回false。调用传入的参数同1类似。
jQuery.each=function( obj, fn, args ) { 
if ( args ) { 
if ( obj.length == undefined ){ 
for ( var i in obj ) 
fn.apply( obj, args ); 
}else{ 
for ( var i = 0, ol = obj.length; i < ol; i++ ) { 
if ( fn.apply( obj, args ) === false ) 
break; 
} 
} 
} else { 
if ( obj.length == undefined ) { 
for ( var i in obj ) 
fn.call( obj, i, obj ); 
}else{ 
for ( var i = 0, ol = obj.length, val = obj[0]; i < ol && fn.call(val,i,val) !== false; val = obj[++i] ){} 
} 
} 
return obj; 
}

需要特别注意的是each方法中fn的具体调用方法并不是采用简单的fn(i,val)或fn(args),而是采用了 fn.call(val,i,val)或fn.apply(obj.args)的形式,这意味着,在你自己的fn的实现中,可以直接采用this指针引用数组或是对象的子元素。这种方式是绝大多数jQuery所采用的一种实现方式。
Array.prototype.contains = function (obj) { 
return this.indexOf(obj) != -1; 
}; 
Array.prototype.copy = function (obj) { 
return this.concat(); 
}; 
Array.prototype.insertAt = function (obj, i) { 
this.splice(i, 0, obj); 
}; 
Array.prototype.insertBefore = function (obj, obj2) { 
var i = this.indexOf(obj2); 
if (i == -1) 
this.push(obj); 
else 
this.splice(i, 0, obj); 
}; 
Array.prototype.removeAt = function (i) { 
this.splice(i, 1); 
}; 
Array.prototype.remove = function (obj) { 
var i = this.indexOf(obj); 
if (i != -1) 
this.splice(i, 1); 
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: