Я пытаюсь получить доступ к свойству объекта, используя динамическое имя. Это возможно?
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, таких как 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
. (Кроме того, ваш код, кажется, имеет некоторые дополнительные обратные слеши, которые не принадлежат ему. Но он все равно будет бессмысленным, даже если вы исправите эту синтаксическую ошибку.)