2016-09-13 44 views
-1

需要幫助創建執行反向淺拷貝的自定義對象類型?例如:如何將淺拷貝一個javascript數組(容器)?

arrayobj.slice(0)返回一個具有相同長度的新數組對象,但每個索引都保持對在原始arrayobj的相同索引處找到的對象的引用。因此,沒有重複的對象

jQuery的延伸或(....) { arr[i] = deepcopy(arr[i]); }返回一個新的數組對象具有相同的長度,並且該新的數組的每個索引持有新/複製該同一索引處具有相同的鍵/值作爲對象的對象原來的arrayobj。

你能幫助我建立構造,可以返回參考同一陣列容器,但每個插槽一個新的/複製的對象?理想的情況下可以強制突變限制不允許推/不印字/彈出/反向/移位/排序/剪接

然而,數組和陣列狀物體之間的一個主要區別是,陣列狀物體從Object.prototype中,而不是繼承Array.prototype。這意味着類似於數組的對象無法訪問常見的數組原型方法。

用例與原始數組對象的狀態有關。因此,如果父陣列容器是一種狀態,位於各指標的子對象將每個按鍵相同,但每個按鍵可以在比如果父陣列容器被認爲是處於不同的狀態不同的屬性值進行設定。另外,保留原始數組的長度非常重要 - 只需根據原始數組的不同狀態來擔心每個插槽中的「行爲」。

非常感謝您的寶貴意見和指導。

+2

*「[] .concat(arrayobj)或arrayobj.concat([])返回與相同長度的新的數組對象和這種新的數組的每個索引持有新的/重複的對象「*這是不正確的。它與使用'.slice'具有相同的結果。您正在尋找一個簡單的'for'循環來迭代數組中的每個元素,克隆它並將其分配回相同的位置。克隆對象不是內置於JavaScript中。請參閱[在JavaScript中深入克隆對象的最有效方法是什麼?](http://stackoverflow.com/q/122102/218196) –

+0

我認爲這裏真正的問題是「如何創建對象的副本?」 – mhodges

+1

@FelixKling https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice「slice()方法返回一個數組的一部分到一個新數組的淺表副本object ...對於對象引用(而不是實際對象),slice將對象引用複製到新數組中。原始數組和新數組引用同一個對象。如果引用的對象更改,則更改對於新的和原始的陣列「。 –

回答

3

是否有一個構造可以返回對同一個數組容器的引用,但是在每個槽中是新的/重複的對象?

正如我在評論中提到的,一個簡單的for循環會爲你做的(假設你已經有了另一種機制,以深拷貝的對象):

for (var i = 0; i < arr.length; i++) { 
    arr[i] = deepcopy(arr[i]); 
} 
+1

downvote的原因是什麼? –

1

是否有一個結構,可用返回對同一個數組 容器的引用,但在每個插槽中是新的/重複的對象?

不,我不這麼認爲。引用同一個數組容器的兩個單獨的值保證了該數組與它當然的內容是同一個數組。

但是,如果你想有通過保持不使參照對應的一個源陣列則可能做如純JS如下在淺對象項的索引關係複製的對象的陣列;

var arr = [{a:1},{b:2}], 
 
    brr = arr.map(o => Object.assign({},o)); 
 
console.log(arr); 
 
console.log(brr); 
 
arr[0].a = 3; 
 
brr[1].b = 4; 
 
console.log(arr); 
 
console.log(brr);

對於深對象轉介,你需要自己的嵌套對象將Object.assign()工作的工具。

1

這是你看着什麼

var a=['asda','sdf','sdfsdfsdf']; 
var b = {}; 
for(var i=0; i<a.length;i++){ 
    b[i]=JSON.parse(JSON.stringify(a[i])); 
} 

console.log(Object.prototype.toString.call(a)); //[Object array] 

console.log(Object.prototype.toString.call(b)); // [Object object] 
1

您可以使用Proxy了點。這是一個創新的事情是JS世界尚未得到廣泛支持,但旨在解決像你一樣的問題

稍微擴展下面的代碼將做你需要的東西。

// base array to extend 
 
let base = [1, 2, 3, 4, 5]; 
 

 
// array of values which will replace values in original array 
 
let extention = [, 12, , 14,]; 
 

 
let prohibitedMethods = ['push']; 
 

 
let proxiedArray = new Proxy(base, { 
 
    get (target, key) { 
 
    console.info(`# Get on property "${key}"`) 
 
    if (prohibitedMethods.indexOf(key) != -1) { 
 
     throw new Error('Prohibited'); 
 
    } 
 
    return extention[key] ? extention[key] : target[key]; 
 
    } 
 
}); 
 

 
for(var i = 0; i < proxiedArray.length; i++) { 
 
    // will write 1, 12, 3, 14, 5 
 
    // as you can see part of the values taken from `extention` array 
 
    console.log(proxiedArray[i]) 
 
} 
 

 
try { 
 
    proxiedArray.push(1); 
 
} catch(e) { 
 
    console.log('Cannot push! and that\'s great'); 
 
}