Я намагаюся отримати доступ до властивості об’єкта за допомогою динамічного імені. Чи можливо це?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Я намагаюся отримати доступ до властивості об’єкта за допомогою динамічного імені. Чи можливо це?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Відповіді:
Є два способи доступу до властивостей об'єкта:
something.bar
something['bar']
Значення між дужками може бути будь-яким виразом. Тому, якщо ім'я властивості зберігається у змінній, вам потрібно використовувати позначення дужок:
var foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected
Це моє рішення:
function resolve(path, obj) {
return path.split('.').reduce(function(prev, curr) {
return prev ? prev[curr] : null
}, obj || self)
}
Приклади використання:
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'})
На JavaScript ми можемо отримати доступ:
foo.bar
foo[someVar]
абоfoo["string"]
Але лише другий випадок дозволяє динамічно отримувати доступ до властивостей:
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
Далі наводиться приклад ES6, як можна отримати доступ до властивості об’єкта, використовуючи ім’я властивості, яке було динамічно генеровано шляхом об'єднання двох рядків.
var suffix = " name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
Це називається обчисленими іменами властивостей
Цього можна досягти досить кількома різними способами.
let foo = {
bar: 'Hello World'
};
foo.bar;
foo['bar'];
Позначення в дужках є особливо потужним, оскільки дозволяє вам отримати доступ до властивості на основі змінної:
let foo = {
bar: 'Hello World'
};
let prop = 'bar';
foo[prop];
Це можна поширити і на циклічне обслуговування над усіма властивостями об'єкта. Це може здатися зайвим через новіші конструкції JavaScript, такі як ... of ..., але допомагає проілюструвати випадок використання:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
for (let prop in foo.getOwnPropertyNames()) {
console.log(foo[prop]);
}
Як точки, так і позначення дужок також працюють, як очікувалося, для вкладених об'єктів:
let foo = {
bar: {
baz: 'Hello World'
}
};
foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;
Руйнування об'єкта
Ми також могли б розглянути деструктурування об'єктів як засіб доступу до властивості в об'єкті, але так:
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'
Ви можете зробити це так, використовуючи Lodash get
_.get(object, 'a[0].b.c');
Я взяв до уваги коментарі нижче і погодився. Евалу слід уникати.
Доступ до властивостей кореня в об'єкті легко досягти obj[variable]
, але отримання вкладених матеріалів ускладнює. Не писати вже написаний код я пропоную використовувати lodash.get
.
Приклад
// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);
// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);
Lodash get можна використовувати різними способами, ось посилання на документацію lodash.get
eval
коли це можливо. stackoverflow.com/questions/86513/…
eval
для чогось тривіального в якості доступу до властивостей є простим надмірним і навряд чи доцільним при будь-яких обставинах. У чому «біда»? obj['nested']['test']
працює дуже добре і не вимагає від вас вставляти код у рядки.
obj['nested']['value']
- пам’ятайте, діти, евал - це зло!
_.get
до столу. Я вважаю, що ця відповідь заслуговує на теперішнє оновлення, а не низових. Це може бути зайвим, але добре знати, що воно існує.
Кожного разу, коли вам потрібно динамічно отримувати доступ до ресурсу, ви повинні використовувати квадратну дужку для доступу не "". Синтаксис оператора
: object [власність}
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])
Я натрапив на випадок, коли я вважав, що хочу передати "адресу" властивості об'єкта як даних іншій функції та заповнити об'єкт (за допомогою AJAX), зробити пошук з адресного масиву та відобразити в цій іншій функції. Я не міг використати позначення крапок, не роблячи строкову акробатику, тому я подумав, що масив може бути замість цього пройти. Я все-таки робив щось інше в будь-якому випадку, але, здавалося, пов’язаний з цією посадою.
Ось зразок об’єкта мовного файлу, як той, з якого я хотів дані:
const locs = {
"audioPlayer": {
"controls": {
"start": "start",
"stop": "stop"
},
"heading": "Use controls to start and stop audio."
}
}
Я хотів мати можливість передавати масив, такий як: ["audioPlayer", "управління", "стоп"] для доступу до мовного тексту, "stop" у цьому випадку.
Я створив цю маленьку функцію, яка шукає параметр "найменш конкретного" (першого) адреси і переназначає повернений об'єкт собі. Тоді він готовий шукати наступний найбільш конкретний параметр адреси, якщо такий існує.
function getText(selectionArray, obj) {
selectionArray.forEach(key => {
obj = obj[key];
});
return obj;
}
використання:
/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs));
/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs));
Це стає цікавим, коли вам доведеться передавати параметри і цій функції.
Код 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
Цей простий фрагмент коду може перевірити наявність глибоко вкладених змінних / значень без необхідності перевіряти кожну змінну попутно ...
var getValue = function( s, context ){
return Function.call( context || null, 'return ' + s )();
}
Вих. - глибоко вкладений масив об'єктів:
a = [
{
b : [
{
a : 1,
b : [
{
c : 1,
d : 2 // we want to check for this
}
]
}
]
}
]
Замість :
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
Зараз ми можемо:
if( getValue('a[0].b[0].b[0].d') == 2 ) // true
Ура!
Я поставив запитання, яке колись повторювалося на цю тему, і після надмірних досліджень і, побачивши, що багато інформації не вистачає, яка повинна бути тут, я відчуваю, що мені є щось цінне додати до цієї старшої публікації.
let properyValue = element.style['enter-a-property'];
проте я рідко йду цим маршрутом, оскільки він не працює на значення властивостей, призначені за допомогою таблиць стилів. Щоб навести вам приклад, я продемонструю за допомогою трохи псевдокоду.
let elem = document.getElementById('someDiv');
let cssProp = elem.style['width'];
Використовуючи приклад коду вище; якщо властивість ширини елемента div, яка зберігалась у змінній 'elem', була викладена у таблиці стилів CSS, а не стилізована всередині її тегу HTML, ви, без сумніву, збираєтесь отримати повернене значення невизначеного, що зберігається всередині змінної cssProp. Невизначене значення виникає тому, що для того, щоб отримати правильне значення, код, записаний всередині таблиці стилів CSS, повинен бути обчислений для того, щоб отримати значення, отже; ви повинні використовувати метод, який обчислить значення властивості, значення якого лежить в таблиці стилів.
function getCssProp(){
let ele = document.getElementById("test");
let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}
W3Schools getComputedValue Doc Це хороший приклад, і ви можете грати з ним, однак, це посилання Mozilla CSS getComputedValue doc детально розповідає про функцію getComputedValue, і її повинен читати будь-який прагне розробник, який не зовсім зрозумів з цього приводу.
$(selector).css(property,value)
... дійсно отримує, і встановлює. Це те, що я використовую, єдиним недоліком є те, що ти познайомишся з JQuery, але це, чесно кажучи, одна з дуже багатьох вагомих причин того, що кожен розробник Javascript повинен вивчити JQuery, він просто робить життя легким і пропонує такі методи, як цей, який недоступний зі стандартним Javascript. Сподіваюся, це комусь допомагає !!!
Для тих, хто хоче встановити значення вкладеної змінної, ось як це зробити:
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
Документація: https://lodash.com/docs/4.17.15#set
Також документація, якщо ви хочете отримати значення: https://lodash.com/docs/4.17.15#get
Вам слід скористатися JSON.parse
, подивіться на 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
вже є рядком, тож `${foo}`
точно так само, як foo
. (Крім того, ваш код, здається, має кілька додаткових нахилів, які там не належать. Але це все одно буде безглуздо, навіть якщо ви виправите цю синтаксичну помилку.)