Tôi đang cố gắng truy cập vào một thuộc tính của một đối tượng bằng tên động. Điều này có thể không?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Tôi đang cố gắng truy cập vào một thuộc tính của một đối tượng bằng tên động. Điều này có thể không?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Câu trả lời:
Có hai cách để truy cập các thuộc tính của một đối tượng:
something.bar
something['bar']
Giá trị giữa các dấu ngoặc có thể là bất kỳ biểu thức nào. Do đó, nếu tên thuộc tính được lưu trữ trong một biến, bạn phải sử dụng ký hiệu ngoặc:
var foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected
Đây là giải pháp của tôi:
function resolve(path, obj) {
return path.split('.').reduce(function(prev, curr) {
return prev ? prev[curr] : null
}, obj || self)
}
Ví dụ sử dụng:
resolve("document.body.style.width")
// or
resolve("style.width", document.body)
// or even use array indexes
// (someObject has been defined in the question)
resolve("part.0.size", someObject)
// returns null when intermediate properties are not defined:
resolve('properties.that.do.not.exist', {hello:'world'})
Trong javascript chúng ta có thể truy cập bằng:
foo.bar
foo[someVar]
hoặcfoo["string"]
Nhưng chỉ trường hợp thứ hai cho phép truy cập các thuộc tính một cách linh hoạt:
var foo = { pName1 : 1, pName2 : [1, {foo : bar }, 3] , ...}
var name = "pName"
var num = 1;
foo[name + num]; // 1
// --
var a = 2;
var b = 1;
var c = "foo";
foo[name + a][b][c]; // bar
Sau đây là một ví dụ ES6 về cách bạn có thể truy cập vào thuộc tính của một đối tượng bằng cách sử dụng tên thuộc tính đã được tạo động bằng cách nối hai chuỗi.
var suffix = " name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
Đây được gọi là tên tài sản tính toán
Bạn có thể đạt được điều này theo nhiều cách khác nhau.
let foo = {
bar: 'Hello World'
};
foo.bar;
foo['bar'];
Ký hiệu khung là đặc biệt mạnh mẽ vì nó cho phép bạn truy cập một thuộc tính dựa trên một biến:
let foo = {
bar: 'Hello World'
};
let prop = 'bar';
foo[prop];
Điều này có thể được mở rộng để lặp qua mọi thuộc tính của một đối tượng. Điều này có thể có vẻ dư thừa do các cấu trúc JavaScript mới hơn như ... của ..., nhưng giúp minh họa trường hợp sử dụng:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
for (let prop in foo.getOwnPropertyNames()) {
console.log(foo[prop]);
}
Cả ký hiệu dấu chấm và dấu ngoặc cũng hoạt động như mong đợi đối với các đối tượng lồng nhau:
let foo = {
bar: {
baz: 'Hello World'
}
};
foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;
Phá hủy đối tượng
Chúng ta cũng có thể coi việc phá hủy đối tượng như một phương tiện để truy cập vào một tài sản trong một đối tượng, nhưng như sau:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
let prop = 'last';
let { bar, baz, [prop]: customName } = foo;
// bar = 'Hello World'
// baz = 'How are you doing?'
// customName = 'Quite alright'
Bạn có thể làm như thế này bằng cách sử dụng Lodash get
_.get(object, 'a[0].b.c');
Tôi đã xem xét ý kiến dưới đây và đồng ý. Eval là để tránh.
Truy cập các thuộc tính gốc trong đối tượng có thể dễ dàng đạt được obj[variable]
, nhưng việc lồng ghép làm phức tạp mọi thứ. Không viết mã đã viết tôi đề nghị sử dụng lodash.get
.
Thí dụ
// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);
// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);
Lodash get có thể được sử dụng theo nhiều cách khác nhau, đây là liên kết đến tài liệu lodash.get
eval
bất cứ khi nào có thể. stackoverflow.com/questions/86513/ cường
eval
cho một cái gì đó tầm thường như truy cập các thuộc tính là quá mức cần thiết và hầu như không được khuyến khích trong bất kỳ trường hợp nào. "Rắc rối" là gì? obj['nested']['test']
hoạt động rất tốt và không yêu cầu bạn phải nhúng mã trong chuỗi.
obj['nested']['value']
- nhớ những đứa trẻ, eval là xấu xa!
_.get
đến bàn. Tôi nghĩ rằng câu trả lời này xứng đáng bây giờ upvote thay vì downvote. Nó có thể là quá mức cần thiết, nhưng thật tốt khi biết nó tồn tại.
Bất cứ khi nào bạn cần truy cập vào tài sản một cách linh hoạt, bạn phải sử dụng dấu ngoặc vuông để truy cập thuộc tính không "." Toán tử
Cú pháp: object [orthy}
const something = { bar: "Foobar!" };
const foo = 'bar';
// something.foo; -- not correct way at it is expecting foo as proprty in something={ foo: "value"};
// correct way is something[foo]
alert( something[foo])
Tôi đã gặp một trường hợp mà tôi nghĩ rằng tôi muốn chuyển "địa chỉ" của một thuộc tính đối tượng dưới dạng dữ liệu sang một hàm khác và điền vào đối tượng (với AJAX), tìm kiếm từ mảng địa chỉ và hiển thị trong hàm khác đó. Tôi không thể sử dụng ký hiệu dấu chấm mà không thực hiện các thao tác nhào lộn chuỗi vì vậy tôi nghĩ rằng một mảng có thể tốt để vượt qua. Cuối cùng tôi đã làm một cái gì đó khác nhau, nhưng dường như liên quan đến bài viết này.
Đây là một mẫu của một đối tượng tệp ngôn ngữ như dữ liệu tôi muốn từ:
const locs = {
"audioPlayer": {
"controls": {
"start": "start",
"stop": "stop"
},
"heading": "Use controls to start and stop audio."
}
}
Tôi muốn có thể vượt qua một mảng như: ["audioPlayer", "controls", "stop"] để truy cập văn bản ngôn ngữ, "dừng" trong trường hợp này.
Tôi đã tạo ra hàm nhỏ này tìm kiếm tham số địa chỉ "ít cụ thể nhất" (đầu tiên) và gán lại đối tượng được trả về cho chính nó. Sau đó, nó đã sẵn sàng để tra cứu tham số địa chỉ cụ thể nhất tiếp theo nếu có.
function getText(selectionArray, obj) {
selectionArray.forEach(key => {
obj = obj[key];
});
return obj;
}
sử dụng:
/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs));
/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs));
Thật thú vị khi bạn phải truyền tham số cho chức năng này.
Mã jsfiddle
var obj = {method:function(p1,p2,p3){console.log("method:",arguments)}}
var str = "method('p1', 'p2', 'p3');"
var match = str.match(/^\s*(\S+)\((.*)\);\s*$/);
var func = match[1]
var parameters = match[2].split(',');
for(var i = 0; i < parameters.length; ++i) {
// clean up param begninning
parameters[i] = parameters[i].replace(/^\s*['"]?/,'');
// clean up param end
parameters[i] = parameters[i].replace(/['"]?\s*$/,'');
}
obj[func](parameters); // sends parameters as array
obj[func].apply(this, parameters); // sends parameters as individual values
Đoạn mã đơn giản này có thể kiểm tra sự tồn tại của biến / giá trị được lồng sâu mà không cần phải kiểm tra từng biến trên đường đi ...
var getValue = function( s, context ){
return Function.call( context || null, 'return ' + s )();
}
Ví dụ. - một mảng sâu của các đối tượng:
a = [
{
b : [
{
a : 1,
b : [
{
c : 1,
d : 2 // we want to check for this
}
]
}
]
}
]
Thay vì :
if(a && a[0] && a[0].b && a[0].b[0] && a[0].b[0].b && a[0].b[0].b[0] && a[0].b[0].b[0].d && a[0].b[0].b[0].d == 2 ) // true
Bây giờ chúng ta có thể:
if( getValue('a[0].b[0].b[0].d') == 2 ) // true
Chúc mừng!
Tôi đã hỏi một câu hỏi trùng lặp về chủ đề này một thời gian trước, và sau khi nghiên cứu quá mức, và thấy rất nhiều thông tin bị thiếu ở đây, tôi cảm thấy mình có một cái gì đó có giá trị để thêm vào bài viết cũ này.
let properyValue = element.style['enter-a-property'];
tuy nhiên tôi hiếm khi đi theo tuyến đường này vì nó không hoạt động trên các giá trị thuộc tính được gán qua biểu định kiểu. Để cho bạn một ví dụ, tôi sẽ chứng minh bằng một chút mã giả.
let elem = document.getElementById('someDiv');
let cssProp = elem.style['width'];
Sử dụng ví dụ mã ở trên; nếu thuộc tính chiều rộng của phần tử div được lưu trữ trong biến 'elem' được tạo kiểu trong biểu định kiểu CSS và không được tạo kiểu bên trong thẻ HTML của nó, bạn chắc chắn sẽ nhận được giá trị trả về của giá trị không xác định được lưu trữ bên trong của biến cssProp. Giá trị không xác định xảy ra bởi vì để có được giá trị chính xác, do đó, mã được viết bên trong CSS Style-Sheet cần được tính toán theo thứ tự để có được giá trị, do đó; bạn phải sử dụng một phương pháp sẽ tính toán giá trị của tài sản mà giá trị của chúng nằm trong biểu định kiểu.
function getCssProp(){
let ele = document.getElementById("test");
let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}
W3Schools getComputingValue Doc Đây là một ví dụ hay và cho phép bạn chơi với nó, tuy nhiên, liên kết này Mozilla CSS getComputingValue doc nói về hàm getComputingValue một cách chi tiết và nên được đọc bởi bất kỳ nhà phát triển khao khát nào không hiểu rõ về chủ đề này.
$(selector).css(property,value)
... không nhận, và không thiết lập. Đó là những gì tôi sử dụng, nhược điểm duy nhất là bạn đã biết JQuery, nhưng đây thực sự là một trong rất nhiều lý do tốt mà mọi Nhà phát triển Javascript nên học JQuery, nó giúp cuộc sống trở nên dễ dàng và cung cấp các phương thức, như cách này, không có sẵn với Javascript tiêu chuẩn. Hy vọng điều này sẽ giúp được ai đó !!!
Đối với bất kỳ ai đang tìm cách đặt giá trị của biến lồng nhau, đây là cách thực hiện:
const _ = require('lodash'); //import lodash module
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.set(object, 'a[0].b.c', 4);
console.log(object.a[0].b.c);
// => 4
Tài liệu: https://lodash.com/docs/4.17.15#set
Ngoài ra, tài liệu nếu bạn muốn nhận giá trị: https://lodash.com/docs/4.17.15#get
Bạn nên sử dụng JSON.parse
, hãy xem https://www.w3schools.com/js/js_json_parse.asp
const obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}')
console.log(obj.name)
console.log(obj.age)
const something = { bar: "Foobar!" };
const foo = 'bar';
something[\`${foo}\`];
foo
đã là một chuỗi, do đó, `${foo}`
chính xác như là foo
. (Ngoài ra, mã của bạn dường như có một số dấu xồ nguợc bổ sung mà không làm thuộc có Nhưng nó vẫn sẽ là vô nghĩa ngay cả khi bạn cố định mà lỗi cú pháp..)