2016-06-24 84 views
-2

我遇到了麻煩接近這個問題,如果我有一個工作解決方案,我懷疑它是最優化的。如何通過參考(模擬)

這裏的問題是:

想象對象的數組,每個對象表示人。

var people = [ 
{id:1, name:"John", points: 50}, 
{id:2, name:"Mark", points: 80}, 
{id:3, name:"Peter", points: 25}, 
]; 

在我們人陣,我們有3人與唯一的ID財產。

現在想象一下,我們有多個功能來修改/更新人員對象。

顯然,這是行不通的,因爲外部對象將不會受到影響由incrementPoints製造()函數的變化 。

var myPerson = people[0]; 

incrementPoints(myPerson){ 
    myPerson.points++; 
}; 

// myPerson.points = 50 
addPoints(myPerson); // We're passing an person object to addPoints; 
// myPerson.points = 50 (Did not change, not affected by addPoints) 

然而,這會工作!但我們支付的價格是 通過人員數組迭代的成本,並匹配所需人員的ID。

function getPersonIndexById(personId){ 
// Iterate through all persons in 'people' array 
for(var index = 0; index < people.length; index++) 
    people[i].id === personId ? return index : continue; 
} 

function incrementPoints(personId){ 
people[ getPersonIndexById(personId) ].points++; 
} 

function decrementPoints(personId){ 
people[ getPersonIndexById(personId) ].points--; 
} 

是否有更好的/簡單/清潔/用於處理這種情況的概念。很明顯,理想的解決方案是通過&引用,但JavaScript不允許這樣做。我並不是試圖實現無用的黑客攻擊,而是理解開發人員在遇到類似情況時所做的工作以及他們如何解決這些問題。

+1

myPerson.points ++;'does work ... varists = [{id:1,name:「John」,points:50},{id:2,name:「Mark」,points:80 },{id:3,name:「Peter」,points:25}]; var myPerson = people [0]; function incrementPoints(myPerson){ myPerson.points ++; }; incrementPoints(myPerson); console.log(myPerson);' - > Object {id:1,name:「John」,points:51} –

+2

...並且它始終有效,因爲對象始終作爲引用的值傳遞。 – adeneo

+0

我認爲...也許不正確,Java傳遞一個值作爲參考。所以,在你的第一個例子中,它實際上會起作用。您無法更改myPerson,但更改myPerson.points會反映在原始對象中。 myPerson是價值物品,但仍引用人物[0]。 –

回答

1
var people = [ 
    {id:1, name:"John", points: 50}, 
    {id:2, name:"Mark", points: 80}, 
    {id:3, name:"Peter", points: 25}, 
]; 

var myPerson = people[0]; 

function incrementPoints(myPerson){ 
    myPerson.points++; 
}; 

function addPropertyToPerson(myPerson, lastname) { 
    myPerson.lastName = lastname; 
} 

// The properties of the myPerson object can still be modified since 
// the value passed in to the function is the reference to the object 
incrementPoints(myPerson); 
console.log(myPerson); 

// Similarly, additional properties can still be added since 
// the value passed in to the function is the reference to 
// the outer object 
addPropertyToPerson(myPerson, "smith"); 
console.log(myPerson); 
+0

令人驚歎!感謝您解決這個問題。另外一個問題,如果你不介意 - 除了明確給myPerson分配另一個值之外,內部對象何時會釋放它對原始對象的引用?如果這甚至可能(通過訪問/編輯內部對象隱式地釋放引用) –

+0

如果我理解了你的新問題,那麼只要函數退出,外部/原始對象的引用就會丟失,除非創建了閉包。每次調用/執行函數時,都會爲其創建一個新的執行上下文,併爲每個新副本重新創建所有變量,參數,作用域鏈等。即使它是一次又一次被調用的相同函數,如果您願意,每次都會重新創建其「機器」。除非像我之前提到的那樣,它會產生封閉。在這種情況下,封閉環境將持續到封閉不再需要。 – juan8a

1
  • 對象作爲參考
  • 你用錯誤的語法定義的名稱incrementPoints功能通過,但您呼叫addPoints。我希望這是一個錯字/錯誤。
  • 如果我想它是addPoints那麼它工作正常。該函數調用後您將獲得51分。
  • 您可以使用Array.prototype.find通過ID找到一個人,它是內置的,它會很快。

function incrementPoints(personId){ 
 

 
     var person = people.find(function(p){ 
 
      return p.id === personId; 
 
     }); 
 
     if (person) { 
 
     person.points++; 
 
     } 
 
    }

+0

這肯定是一個錯字,它只對你理解你所做的問題很重要。 Array.prototype.find看起來很棒。但是因爲對象是作爲參考傳遞的,所以它非常簡單。謝謝 –

0

我寧願轉換陣列,同時在獲取數據映射。

var personMap = {}; people.forEach(function(person){ personMap[id] = person; });

有了這個,現在你有地圖

你可以得到某人爲personMap[personId]

這裏創建地圖是一個時間的活動,所以你需要一個單輪迭代

請耐心等待我的回覆..我正在回覆手機,所以格式化可能不會od

+0

格式化看起來不錯。我剛剛瞭解到對象是作爲引用傳遞的,這意味着映射id或通過數組索引訪問數組中的對象並不是最佳解決方案(對於這種情況),因爲我們可以簡單地傳遞對象並對其進行變更,這是最簡單的最快的解決方案。 –