Я пытаюсь получить доступ к свойству объекта, используя динамическое имя. Это возможно?
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.barsomething['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, таких как for ... 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']- помните детей, Eval это зло!
_.getк столу. Я думаю, что этот ответ заслуживает теперь положительных, а не отрицательных голосов. Это может быть излишним, но хорошо знать, что оно существует.
Всякий раз, когда вам нужен динамический доступ к свойству, вы должны использовать квадратную скобку для доступа к свойству, а не "." Синтаксис оператора
: object [Propery}
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», «controls», «stop»] для доступа к тексту языка, в этом случае «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 )();
}
Ex. - глубоко вложенный массив объектов:
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'];
Используя пример кода выше; если свойство width элемента div, который был сохранен в переменной 'elem', было стилизовано в таблице стилей CSS, а не внутри его тега HTML, вы, без сомнения, получите возвращаемое значение undefined, хранящееся внутри переменной 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 Developer должен изучать 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. (Кроме того, ваш код, кажется, имеет некоторые дополнительные обратные слеши, которые не принадлежат ему. Но он все равно будет бессмысленным, даже если вы исправите эту синтаксическую ошибку.)