2012-07-02 60 views
1

來自面向對象的JavaScript書籍的問題:想象一下Array()不存在,並且數組文字符號也不存在。創建一個名爲MyArray()的構造函數,其行爲儘可能接近Array()。仿真數組對象

我認爲這是一個很好的挑戰來測試我的技能。這是我想出了,但它不工作,是非常不完整的..我有點爲難:

function MyArray(){ 

// PRIVATE FIELDS ----------------------- 

var initialData = arguments; 
var storage; 

// PRIVATE METHODS ---------------------- 

function refresh(){ //this doesn't work :(
    for(var i = 0; i < storage.length; i++){ 
     this[i] = storage[i] 
    } 
}; 

function initialize(){ 
    storage = initialData; 
    refresh(); 
} 

function count(){ 
    var result = 0; 
    for(var item in this){ 
     //console.log(item, parseInt(item), typeof item); 
     if(typeof item == 'number'){ 
      result++; 
     } 
    } 
    return result; 
}; 

initialize(); 

// PUBLIC FIELDS ------------------------- 

this.length = count(); 

// PUBLIC METHODS ------------------------ 

//todo: 
this.push = function(item){ 
    refresh(); 
} 

this.pop = function(){} 

this.join = function(){} 

this.toString = function(){} 

} 

var c = new MyArray(32,132,11); 

console.log(c, c.length); 

這不是任何生產代碼或任何項目..只是嘗試學習JavaScript更多。任何人都可以嘗試使用此代碼來幫助我?

+1

關於Array對象的關鍵是「length」屬性是魔術。一旦Harmony對象代理變得真實,像這樣的事情就不會那麼難。 – Pointy

+2

所以你使用數組來複制數組?即使作爲練習,它對我來說也沒有多大意義。如果您想學習繼承和高級主題,我建議您從[基本JavaScript設計模式](http://addyosmani.com/resources/essentialjsdesignpatterns/book/) – elclanrs

+0

@elclanrs,該書的+1,謝謝。 – corazza

回答

2

問題是你可以使用arguments對象。它不是使用Array()創建的數組,因此您不會破壞練習的規則。這裏有您需要做什麼:

this.length = 0; 
for (var i in arguments) { 
    this[this.length] = arguments[i]; 
    this.length++; 
} 

我忘了提,任何對象是關聯數組,所以它不是申請關聯數組的鍛鍊,因爲我們不使用Array()對象錯誤的事情本身。

要的問題筆者:在你的例子中,你使用:這個[ 「我」] =存儲[I]那等於this.i =存儲[I]。嘗試刪除引號,並使用它像這[i] =存儲[i]

+0

注意'for in'循環中,它們可以迭代內置的屬性,例如'toString'。 – Florent

+0

對於使用對象的一般情況,這是TRUE,但在這種情況下,我使用arguments-object:當遍歷它時,我們只獲取函數參數(參數) – Alex

0
for(var item in this){ 
    if(typeof item == 'number') 

屬性名稱始終是一個字符串。您需要檢查它是否是從0到MaxArrayLength的數字的字符串表示形式。例如,你可以做

for (var i=0; i<4294967296; i++) 
    if (i in this) 
     result = i; 

您可能也有興趣thesearticlesofficial specification for Array behaviour

+0

我試圖通過這[1],這[2],這[3]這將像「索引」,但屬性格式..通過我的'刷新()函數,我將如何能夠通過數字命名的屬性進行篩選? –

+0

我已經取消了我的回答,這是你想要的嗎? – Bergi

0

我目前正在瀏覽這本書,我可能應該嘗試一些更近期,但它並沒有過時而校長們依然健全......他們在我看來是這樣。

無論如何,我採取了一種稍微不同的解決方案,雖然我從他的操作靈感中學習如何處理字符串。我認爲這個練習的挑戰不是要創建更多的陣列,否則......這是一個瘋狂的挑戰,特別是對於新語言的人來說。

var MyArray = function() { 
    var args = arguments; 
    var length = 0; 
    for each(var item in args) { 
     this[length++] = item; 
    } 
    this.toString = function() { 
    var result = args[0]; 
    for (var i = 1; i < args.length; i++) { 
     result += ',' + args[i]; 
    } 
    return result; 
    } 
    this.length = length; 
    this.push = function (push) { 
     var newLength = args.length++; 
     args[newLength] = push; 
     this[newLength] = push; 
     return ++length; 
    } 
    this.pop = function() { 
     delete args[--args.length]; 
     delete this[args.length]; 
     length--; 
     return args; 
    } 
    this.join = function(joiner){ 
     if(typeof arguments[0] === "undefined"){ 
      joiner = ','; 
     } 
     var result = args[0]; 
     for (var i = 1; i < args.length; i++) { 
      result += joiner + args[i]; 
     } 
     return result; 
    } 
} 
var a = new MyArray(1, 2, 3, 'test'); 
console.log(a.toString()); 
console.log(a[a.length - 1]); 
console.log(a.push('boo')); 
console.log(a.toString()); 
console.log(a.pop()); 
console.log(a.toString()); 
console.log(a.join(',')); 
a.join(' isn\'t ');