2016-03-11 17 views
10

Giả sử tôi có các đối tượng sau đây:Làm cách nào để hủy cấu trúc thành các biến được đặt tên động trong ES6?

const user = { 
    id: 42, 
    displayName: "jdoe", 
    fullName: { 
     firstName: "John", 
     lastName: "Doe" 
    } 
}; 

Và rằng tôi muốn chỉ idfullName.

tôi sẽ làm như sau:

const { id, fullName } = user 

Dễ dàng peasy, phải không?

Bây giờ, giả sử rằng tôi muốn thực hiện phá hủy dựa trên giá trị của biến số khác được gọi là fields.

const fields = [ 'id', 'fullName' ] 

Bây giờ câu hỏi của tôi là: Làm cách nào để tôi có thể hủy dựa trên một loạt khóa?

Tôi không biết xấu hổ thử như sau nhưng không thành công:

let {[{...fields}]} = userlet {[...fields]} = user. Có cách nào mà điều này có thể được thực hiện?

Cảm ơn bạn

+1

Dưới đây là một câu hỏi liên quan về destructuring tất cả các thuộc tính: http://stackoverflow.com/ question/31907970/how-do-i-destructure-all-properties-in-the-current-range-closure-in-es2015 - Có lẽ câu trả lời tương tự được áp dụng ở đây – CodingIntrigue

+0

Nếu 'trường' được thay đổi thành một mảng trống thì bạn sẽ không tạo ra biến nào và bất kỳ mã nào sau đó sẽ bị nguy hiểm. Sử dụng một const với literals đảm bảo rằng nguy cơ có thể được xác định trước nhưng một cái gì đó như 'fields = nonliteralvar' sẽ tạo ra vấn đề. –

Trả lời

4

Câu trả lời ngắn gọn: điều đó là không thể và sẽ không thể thực hiện được.

Lý do đằng sau điều này: nó sẽ giới thiệu các biến được đặt tên động mới vào phạm vi khối, có hiệu quả là động eval, do đó vô hiệu hóa bất kỳ tối ưu hóa hiệu suất nào. Dynamic eval có thể thay đổi phạm vi bay luôn được coi là cực kỳ nguy hiểm và đã bị loại bỏ khỏi chế độ nghiêm ngặt của ES5.

Hơn nữa, nó sẽ là một mùi mã - tham chiếu biến không xác định ném ReferenceError, vì vậy bạn sẽ cần thêm mã bản mẫu để xử lý một cách an toàn phạm vi động như vậy.

+0

Đó thực sự là một mùi mã. Đã kết thúc bằng cách sử dụng cách tiếp cận khác. – Anass

+1

Điểm phạm vi bạn tăng là không thể thực hiện được. Có, tuy nhiên, ít nhất một trường hợp trong đó nó không phải là một mùi mã cho mỗi se. Tức là, khi bạn có một hàm chấp nhận một khóa hoặc các khóa được sử dụng trong lần lặp lại. Các phiên bản đặc biệt của 'omit',' pluck' & 'reduce' là tất cả các trường hợp mà việc phá hủy động sẽ hỗ trợ khả năng đọc. Phân bổ động tên trường trong một đối tượng là có thể và là một cách tuyệt vời để bật mã DRYer (tức là chia sẻ mã nhiều hơn). Trong cùng một cách, phân bổ động của con trỏ có thể giúp DRY lên mã mà không cần phải sử dụng một hashmap để phá vỡ một giới hạn ngôn ngữ. –

6

Không thể hủy cấu trúc bằng khóa động. Để ngăn chặn vấn đề tạo các biến động (như Ginden đã đề cập), bạn cần cung cấp bí danh.

const user = { 
    id: 42, 
    displayName: "jdoe", 
    fullName: { 
     firstName: "John", 
     lastName: "Doe" 
    } 
}; 

const fields = [ 'id', 'fullName' ]; 
const object = {}; 

const {[fields[0]]: id, [fields[1]]: fullName} = user; 

console.log(id); // 42 
console.log(fullName); // { firstName: "John", lastName: "Doe" } 

Để giải quyết vấn đề phải xác định bí danh tĩnh cho giá trị động, bạn có thể gán cho thuộc tính động của đối tượng. Trong ví dụ đơn giản này, đây là giống như quay trở lại toàn bộ destructuring, mặc dù :)

const user = { 
    id: 42, 
    displayName: "jdoe", 
    fullName: { 
     firstName: "John", 
     lastName: "Doe" 
    } 
}; 

const fields = [ 'id', 'fullName' ]; 
const object = {}; 

({[fields[0]]: object[fields[0]], [fields[1]]: object[fields[1]]} = user); 

console.log(object.id); // 42 
console.log(object.fullName); // { firstName: "John", lastName: "Doe" } 

nguồn:

+2

Thật không may là các giải pháp được đề xuất của bạn sẽ trả lời câu hỏi khi được hỏi. –

0

Như đã thảo luận trước đây, bạn không thể phá hủy vào vari được đặt tên động ables trong JavaScript mà không cần sử dụng eval.

Nhưng bạn có thể có được một tập hợp con của các đối tượng tự động, sử dụng giảm chức năng như sau:

const destruct = (keys, obj) => 
 
    keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {}); 
 

 
const object = { 
 
    color: 'red', 
 
    size: 'big', 
 
    amount: 10, 
 
}; 
 

 
const subset = destruct(['color', 'amount'], object); 
 
console.log(subset);

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