2017-01-11 26 views
10

Tôi có một Object a như thế:Object.assign-override lồng sở hữu

const a = { 
    user: { 
    … 
    groups: […] 
    … 
    } 
} 

trong đó có rất nhiều tài sản trong a.user

Và tôi muốn thay đổi chỉ có giá trị a.user.groups. Nếu tôi làm điều này:

const b = Object.assign({}, a, { 
    user: { 
    groups: {} 
    } 
}); 

b không có bất kỳ tài sản nào khác ngoài b.user.groups, tất cả những người khác sẽ bị xóa. Có cách nào ES6 để chỉ thay đổi thuộc tính lồng nhau, mà không mất tất cả các khác, với Object.assign?

+2

có vẻ như đang làm những gì 'Object.assign' được cho là. Nó đang thay đổi thuộc tính 'user' bằng đối tượng mới mà bạn cung cấp. Nếu đó là điều duy nhất bạn muốn thay đổi tại sao bạn không chỉ đơn giản là làm 'b.user.groups =/* value * /'? – taguenizy

Trả lời

23

Sau khi một số cố gắng tôi có thể tìm một giải pháp mà trông khá đẹp như thế:

const b = Object.assign({}, a, { 
    user: { 
    ...a.user, 
    groups: 'some changed value' 
    } 
}); 

Để làm cho câu trả lời đó hoàn chỉnh hơn ở đây một ghi chú nhỏ:

const b = Object.assign({}, a) 

là cơ bản giống như:

const b = { ...a } 

vì nó chỉ là bản sao tất cả các thuộc tính của a (...a) cho một đối tượng mới. Vì vậy, các lon trên viết như sau:

const b = { 
    ...a,   //copy everything from a 
    user: {  //override the user property 
     ...a.user, //same sane: copy the everything from a.user 
     groups: 'some changes value' //override a.user.group 
    } 
} 
6

Bạn có thể thay đổi nó theo cách này,

const b = Object.assign({}, a, { 
    user: Object.assign({}, a.user, { 
      groups: {} 
     }) 
}); 

hoặc chỉ làm,

const b = Object.assign({}, a); 
b.user.groups = {}; 
+2

không biến đổi 'b.user.groups',' user' được chia sẻ trên b và a! – borovsky

3

Phương pháp Object.assign() được sử dụng để sao chép các giá trị của tất cả các thuộc tính riêng đếm được từ một hoặc nhiều đối tượng nguồn cho một đối tượng mục tiêu. Nó sẽ trả về đối tượng đích.

phương thức gán sẽ tạo đối tượng mới bằng cách sao chép từ đối tượng nguồn, vấn đề nếu bạn thay đổi bất kỳ phương pháp nào sau này trong đối tượng nguồn sẽ không được phản ánh đối tượng mới.

Sử dụng tạo()

Phương pháp Object.create() tạo ra một đối tượng mới với các đối tượng nguyên mẫu quy định và tài sản.

const b = Object.create(a) 
b.user.groups = {} 
// if you don't want the prototype link add this 
// b.prototype = Object.prototype 

Bằng cách này bạn có b liên kết với một thông qua nguyên mẫu và nếu bạn thực hiện bất kỳ thay đổi trong một, nó sẽ được phản ánh trong b, và bất kỳ thay đổi trong b sẽ không ảnh hưởng đến một

+0

Đó thực sự là một điểm thú vị, nhưng trong trường hợp này tôi cần phải tạo một bản sao của nguồn. – philipp

+0

Sau đó, câu trả lời của riêng bạn là những gì bạn đang tìm kiếm –

+0

Hoặc sử dụng create() và sau đó thực hiện. b.prototype = Object.prototype –

3

Bạn hỏi đặc biệt cho một cách ES6 với Object.assign, nhưng có lẽ ai đó sẽ thích câu trả lời 'chung' hơn của tôi - bạn có thể làm điều đó dễ dàng với lodash, và cá nhân tôi nghĩ rằng giải pháp này dễ đọc hơn.

import * as _ from 'lodash'; 
_.set(a, 'user.groups', newGroupsValue); 

Nó làm thay đổi đối tượng.

+0

có thể, nhưng nó đòi hỏi một thư viện khác ... – philipp

+1

Tất nhiên, đó là lý do tại sao tôi cho rằng bạn không muốn sử dụng giải pháp của tôi nhưng ai đó có vấn đề tương tự có thể thấy nó hữu ích. –

Các vấn đề liên quan