2011-08-02 39 views
19
var arr = { foo : 1, bar: { baz : 2 }, bee : 3 } 

function getter(variable) { 
    return arr[variable]; 
} 

Nếu tôi muốn 'foo' vs 'bee' tôi có thể làm arr[variable] - thật dễ dàng và chức năng thực hiện điều đó.Trong javascript làm thế nào tôi có thể tự động nhận được thuộc tính lồng nhau của một đối tượng

Nhưng điều gì xảy ra nếu tôi muốn nhận được arr.bar.baz AKA arr[bar][baz]?

Tôi có thể chuyển đến hàm getter để cho phép tôi làm điều đó, (và tất nhiên cũng cho phép tôi lấy các thuộc tính không lồng nhau bằng cùng một hàm).

Tôi đã thử getter('bar.baz')getter('[bar][baz]') nhưng những thứ đó không hiệu quả.

Tôi cho rằng tôi có thể phân tích cú pháp dấu chấm hoặc dấu ngoặc vuông (như tại đây: In javascript, test for property deeply nested in object graph?). Có cách nào sạch hơn không? (Bên cạnh việc đánh giá khóa học.)

Đặc biệt là vì tôi cần thiết lập đúng mức nhiều lần trong một vòng lặp cho một loạt các phần tử mảng.

+0

Tại sao bạn không chỉ sử dụng cách tiếp cận đó từ câu hỏi được liên kết? – Shi

+0

Chủ yếu là do chi phí gọi hàm thường xuyên, và nếu có cách nào tốt hơn thì tôi muốn học nó. – Ariel

Trả lời

9

Làm thế nào về sự thay đổi chức năng getter chữ ký như getter('bar', 'baz') thay

function getter() { 
    var v = arr; 
    for(var i=0; i< arguments.length; i++) { 
    if(!v) return null; 
    v = v[arguments[i]]; 
    } 
    return v; 
} 

ps. không kiểm tra, nhưng bạn có ý tưởng;)

1

Bạn có thể truy cập các đối số chức năng nơi bạn có thể vượt qua bất kỳ số chuỗi nào. tôi cũng khuyên bạn nên sử dụng arr như một tham số cho đóng gói tốt hơn:

function getter() { 
    var current = arguments[0]; 
    for(var i = 1; i < arguments.length; i++) { 
     if(current[arguments[i]]) { 
      current = current[arguments[i]]; 
     } else { 
      return null; 
     } 
    } 
    return current; 
} 

var arr = { foo : 1, bar: { baz : 2 }, bee : 3 }; 
var baz = getter(arr, 'bar', 'baz'); 
30

Bạn có thể sử dụng một chức năng truy cập sâu dựa trên một chuỗi cho con đường. Lưu ý rằng bạn không thể có bất kỳ dấu chấm nào trong tên thuộc tính.

function getPropByString(obj, propString) { 
    if (!propString) 
     return obj; 

    var prop, props = propString.split('.'); 

    for (var i = 0, iLen = props.length - 1; i < iLen; i++) { 
     prop = props[i]; 

     var candidate = obj[prop]; 
     if (candidate !== undefined) { 
      obj = candidate; 
     } else { 
      break; 
     } 
    } 
    return obj[props[i]]; 
} 

var obj = {foo: {bar: {baz: 'x'}}}; 

alert(getPropByString(obj, 'foo.bar.baz')); // x 
alert(getPropByString(obj, 'foo.bar.baz.buk')); // undefined 

Nếu chuỗi truy cập trống, trả về đối tượng. Nếu không, tiếp tục đi dọc theo đường dẫn truy cập cho đến lần truy cập cuối cùng thứ hai. Nếu đó là một ojbect, trả về giá trị object[accessor] cuối cùng. Nếu không, trả về không xác định.

1

Theres một chức năng được xác định on this blog để đọc một cách an toàn tính lồng nhau từ một đối tượng JS

Nó cho phép bạn khai thác một đối tượng đối với tài sản ... tức.

safeRead(arr, 'foo', 'bar', 'baz'); 

và nếu bất kỳ một phần của chuỗi đối tượng là null hoặc không xác định nó sẽ trả về một chuỗi rỗng ....

12

Sử dụng phương pháp thư viện lodash sẽ là một cách tiếp cận tốt hơn: - https://lodash.com/docs#get

_.get(arr, 'bar.baz'); //returns 2; 
_.get(arr, 'bar.baz[5].bazzz'); //returns undefined wont throw error; 
_.get(arr, 'bar.baz[5].bazzz', 'defaultvalue'); // Returns defaultValue because result is undefined 
+1

Cảm ơn bạn, đó là chính xác những gì tôi đang tìm kiếm. Người bạn '_.set' của nó cũng thực sự hữu ích. –

0

Gần đây tôi đã phát triển phương pháp Object của riêng mình để có được một thuộc tính đối tượng được lồng giữa các đối tượng và mảng bất kể nó sâu bao nhiêu. Nó sử dụng một dòng duy nhất của phương pháp đệ quy. Kiểm tra này ra.

Object.prototype.getNestedValue = function(...a) { 
 
    return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]]; 
 
}; 
 

 
var myObj = { foo : 1, bar: { baz : 2 }, bee : 3 }, 
 
    bazval = myObj.getNestedValue("bar","baz"); 
 

 
document.write(bazval);

Bây giờ hãy kiểm tra một lồng nhau sâu sắc hơn đối tượng mảng cấu trúc dữ liệu kết hợp

Object.prototype.getNestedValue = function(...a) { 
 
    return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]]; 
 
}; 
 

 
var myArr = [{fox: [{turn:[857, 432]}]}, {sax: [{pana:[777, 987]}]}, {ton: [{joni:[123, 567]}]}, {piu: [{burn:[666, 37]}]}, {sia: [{foxy:[404, 696]}]}]; 
 
    
 
document.write(myArr.getNestedValue(3,"piu",0,"burn",1));

Tôi tin rằng có khả năng vượt qua các thông số tìm kiếm tự động với các phương pháp existing array sẽ thực hiện các hành động như tìm kiếm, lọc o r thay thế cấu trúc lồng nhau sâu sắc dễ dàng.

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