当前位置: 首页 > 图文教程 > 网络编程 > Javascript > javascript Array对象使用小结

Javascript
jQuery中isFunction方法的BUG修复
将函数的实际参数转换成数组的方法
javascript 删除数组中重复项(uniq)
js 巧妙去除数组中的重复项
javascript下一种表单元素获取方法存在的问题
javascript 三种数组复制方法的性能对比
js 多层叠的TAB选项卡
javascript 自动标记来自搜索结果页的关键字
起点页面传值js,有空研究学习下
javascript 的Document属性和方法集合
JavaScript 使用简略语法创建对象的代码
使用JQuery进行跨域请求
jquery 经典动画菜单效果代码
jquery 常用操作方法
js提示信息jtip封装代码,可以是图片或文章
javascript面向对象的方式实现的弹出层效果代码
jquery中的sortable排序之后的保存状态的解决方法
js或css实现滚动广告的几种方案
使用JavaScript库还是自己写代码?
js 右键菜单,支持不同对象不同菜单(兼容IE、Firefox)

Javascript 中的 javascript Array对象使用小结


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2010-01-10   浏览: 90 ::
收藏到网摘: n/a

数组是一段线性分配的内存,它通过整数去计算偏移并访问其中的元素。数组是很快的数据结构,但不幸的是,Javascript并没有像这种数组一样的数据结构。 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()

[Ctrl+A 全选 提示:你可先修改部分代码,再按运行]


[Ctrl+A 全选 提示:你可先修改部分代码,再按运行]


[Ctrl+A 全选 提示:你可先修改部分代码,再按运行]

判断一个变量引用的对象是否为数组。
复制代码 代码如下:

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);
};