文章目錄
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 全選 注:如需引入外部Js需重新整理才能執行]
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
[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)); })
Firefox官網還有一個實現: 複製代碼 代碼如下: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);
};