2011-08-05 33 views
1

我想創建一個可以按照以下方式工作的輔助對象:
它是一個具有給定行數的數組,例如,假設它只能包含3行。
它將具有插入所述第一索引處的一個新的項,並按下一個索引向下所有其餘的插入方法(新條目是0,0變爲1,1 - > 2等。)
並且如果數組已滿到最大行數,最後一個條目退出。
使用自定義方法創建一個有限數組

所以,我提出了以下方法:

function limArray(array, maxlength){ 

    this.arr = array; 
    this.maxlength = maxlength; 
    this.arr.length = maxlength; 

    this.insertVal = function(value){ //insert new value and push down the rest 

     for (var i=maxlength; i>=0; i--) { 
      this.arr[i] = this.arr[i-1] 
     }; 
     this.arr[0] = value; 
     this.arr.length = maxlength; 
    }; 
} 

我的問題是,如果它是使這個聰明的辦法?
是否有可能創建Array對象本身的實例並將其修改爲受限等。
歡迎任何批評/改進建議!

回答

2

你可以覆蓋push方法:

function limArray(array, maxlength){ 
    var push_ = array.push, 
     slice_ = [].slice; 

    array.push = function() { 
     var values = slice_.call(arguments, 0, maxlength - this.length); 
     return push_.apply(this, values); 
    } 
    return array; 
} 

由於@alnorth29 mentioned,你可以使用unshift前面加上一個值。您可以覆蓋這個問題,以及:

function limArray(array, maxlength){ 
    // push like above 
    var unshift_ = array.unshift; 
    array.unshift = function() { 
     unshift_.apply(this, arguments); 
     this.length = this.length > maxlength ? maxlength : this.length; 
     return this.length; 
    } 

    return array; 
} 

當然你也可以用一個更富有表現力的名字附加一個新的屬性比unshift

array.prepend = array.unshift; 

如果要擴展一個這樣的數組實例,請確保您僅使用for循環遍歷其元素,而不使用for...in循環(無論如何,您總是應該使用for)。另一種可能性是使用ECMAScript 5的Object.defineProperty[docs]定義財產並將enumerable設置爲false。但它只在較新的瀏覽器中受支持。

還有其他方法可以將元素添加到數組中,但我認爲您不會使用它們。

用法:

> var limited = limArray([], 3); 
> limited.push(1,2,3,4); 
    3 
> limited 
    [1, 2, 3] 
> limited.push(5) 
    3 
> limited 
    [1, 2, 3] 

> var limited = limArray([], 3); 
> limited.unshift(3, 4) 
    2 
> limited 
    [3, 4] 
> limited.unshift(1, 2) 
    3 
> limited 
    [1, 2, 3] 

更新:

我忘記了,如果傳遞給函數的陣列已經超過元件的最大數目,則不得不減少長度:

function limArray(array, maxlength){ 
    array.length = array.length > maxlength ? maxlength : array.length; 
    //... 

    return array; 
} 
+0

該操作想要有一個方法,在數組的開始插入值,而不是在最後。 – alnorth29

+0

@ alnorth29:更新了我的答案。 –

+0

@Felix Kling thanx的詳細解答!你爲什麼給主函數和內函數一個'return'而不是像我一樣將數組保存在一個內部變量中? – ilyo

1

這對我來說看起來很好,但您可以使用array's unshift method將值添加到數組的起始位置,而不是手動更新所有數值。這將使它更緊湊。

function limArray(array, maxlength){ 

    this.arr = array; 
    this.maxlength = maxlength; 
    this.arr.length = maxlength; 

    this.insertVal = function(value){ //insert new value and push down the rest 
     this.arr.unshift(value); 
     this.arr.length = maxlength; 
    }; 
} 

據我所知,沒有內置的方法來定義數組的最大長度。

+0

如果數組的長度超過maxlength,則只應將'this.arr.length'設置爲'maxlength'。 –