2013-08-12 44 views
11

Tôi có cấu trúc dữ liệu dựa trên json với các đối tượng chứa các đối tượng lồng nhau. Để truy cập vào một phần tử dữ liệu cụ thể, tôi đã liên kết các tham chiếu đến các thuộc tính đối tượng với nhau. Ví dụ:Truy cập các đối tượng lồng nhau Javascript an toàn

var a = b.c.d; 

Nếu b hoặc b.c không xác định, điều này sẽ không có lỗi. Tuy nhiên, tôi muốn nhận được một giá trị nếu nó tồn tại nếu không chỉ là không xác định. Cách tốt nhất để làm điều này mà không cần phải kiểm tra xem mọi giá trị trong chuỗi có tồn tại không?

Tôi muốn giữ cho phương pháp này như chung càng tốt vì vậy tôi không cần phải thêm số lượng lớn các phương pháp helper như:

var a = b.getD(); 

hoặc

var a = helpers.getDFromB(b); 

Tôi cũng muốn thử để tránh các cấu trúc try/catch vì đây không phải là lỗi nên việc sử dụng try/catch có vẻ không đúng chỗ. Điều đó có hợp lý không?

Bất kỳ ý tưởng nào?

+2

http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key?rq=1 – goat

Trả lời

5

Bạn có thể tạo một phương pháp chung mà truy cập vào một yếu tố dựa trên một loạt các tên thuộc tính đó được hiểu như là một con đường thông qua các thuộc tính:

function getValue(data, path) { 
    var i, len = path.length; 
    for (i = 0; typeof data === 'object' && i < len; ++i) { 
     data = data[path[i]]; 
    } 
    return data; 
} 

Sau đó, bạn có thể gọi nó với:

var a = getValue(b, ["c", "d"]); 
+0

Cho rằng ab === a ['b'] tôi giả định rằng sử dụng chuỗi để tham chiếu các đối tượng được coi là thực hành tốt nhất trong JS? – Hubris

+0

@Hubris - Tên thuộc tính luôn là chuỗi. Ký hiệu dấu chấm được coi là "đường cú pháp" (thậm chí không hoạt động nếu tên thuộc tính là từ dành riêng hoặc không phải là mã định danh JS hợp lệ). –

+0

Ok, đó là những gì tôi nghĩ. Tuyệt vời. Cảm ơn bạn :) – Hubris

6

Cách tiếp cận tiêu chuẩn:

var a = b && b.c && b.c.d && b.c.d.e; 

là khá nhanh nhưng không quá thanh lịch (es đặc biệt với tên thuộc tính dài hơn).

Sử dụng các hàm để di chuyển các thuộc tính đối tượng JavaScipt không hiệu quả cũng không thanh lịch.

Hãy thử điều này thay vì:

try { var a = b.c.d.e; } catch(e){} 

trong trường hợp bạn chắc chắn rằng a không được sử dụng trước đó hoặc

try { var a = b.c.d.e; } catch(e){ a = undefined; } 

trong trường hợp bạn có thể gán nó trước đây.

Điều này thậm chí còn nhanh hơn tùy chọn đầu tiên.

0

Nếu bạn muốn có quyền truy cập động với số lượng bất động sản bất thường trong tay, trong ES6 bạn có thể dễ dàng thực hiện như sau;

function getNestedValue(o,...a){ 
 
    var val = o; 
 
    for (var prop of a) val = typeof val === "object" && 
 
            val !== null  && 
 
            val[prop] !== void 0 ? val[prop] 
 
                 : undefined; 
 
    return val; 
 
} 
 
var obj = {a:{foo:{bar:null}}}; 
 
console.log(getNestedValue(obj,"a","foo","bar")); 
 
console.log(getNestedValue(obj,"a","hop","baz"));

1

Đây là một câu hỏi cũ và bây giờ với các tính năng es6, vấn đề này có thể được giải quyết dễ dàng hơn.

const idx = (p, o) => p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o); 

Nhờ @sharifsbeat cho số solution này.

0

lẽ nó có thể đơn giản:

let a = { a1: 11, b1: 12, c1: { d1: 13, e1: { g1: 14 }}} 
console.log((a || {}).a2); => undefined 
console.log(((a || {}).c1 || {}).d1) => 13 

và vân vân.

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