9

Доступ к свойству объекта с динамически вычисляемым именем

10

Я пытаюсь получить доступ к свойству объекта, используя динамическое имя. Это возможно?

const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // Идея в том, чтобы получить доступ к something.bar и получить "Foobar!"

5 ответ(ов)

1

Вот моё решение:

function resolve(path, obj) {
    return path.split('.').reduce(function(prev, curr) {
        return prev ? prev[curr] : null
    }, obj || self)
}

Примеры использования:

resolve("document.body.style.width")
// или
resolve("style.width", document.body)
// также можно использовать индексы массивов
// (someObject был определён в вопросе)
resolve("part.0.size", someObject) 
// возвращает null, если промежуточные свойства не определены:
resolve('properties.that.do.not.exist', {hello: 'world'})

Если у вас есть дополнительные вопросы или требуется объяснение, не стесняйтесь спрашивать!

0

В 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'

В этом примере мы создаем объект foo, имеющий несколько свойств. Используя переменные для создания имен свойств, мы можем динамически получать доступ к ним через квадратные скобки, что дает большую гибкость при работе с объектами.

0

Вы можете достичь этого несколькими разными способами.

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 of Object.getOwnPropertyNames(foo)) {
    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'

Таким образом, вы получаете доступ к свойствам объекта несколькими способами, в зависимости от ваших потребностей и предпочтений.

0

Вы можете сделать это следующим образом, используя метод get из библиотеки Lodash:

_.get(object, 'a[0].b.c');

Этот метод позволяет безопасно извлекать значения из объектов, даже если промежуточные свойства отсутствуют. Если путь не существует, _.get вернет undefined вместо того, чтобы выдать ошибку.

0

В вашем случае вы правильно подошли к задаче, пытаясь получить доступ к вложенным свойствам объекта при помощи массива ключей. Это действительно сложно сделать с помощью нотации точек, особенно когда вам приходится использовать строки для обозначения каждого уровня вложенности. Ваше решение с использованием функции getText выглядит очень удобно.

Функция, которую вы написали, последовательно проходит по массиву ключей и использует их для доступа к вложенным свойствам объекта. В результате, вашим задачей становится извлечение значения по переданным ключам.

Ваш пример кода иллюстрирует это довольно хорошо:

function getText(selectionArray, obj) {
  selectionArray.forEach(key => {
    obj = obj[key];
  });
  return obj;
}

Такое решение позволяет динамически получать доступ к значениям, что может быть весьма полезным, когда структура объекта известна заранее, но конкретные ключи могут быть переданы извне.

С точки зрения использования вашей функции, вы можете легко извлечь текст, как показано в ваших примерах:

console.log(getText(["audioPlayer", "controls", "stop"], locs)); // возвращает 'stop'
console.log(getText(["audioPlayer", "heading"], locs)); // возвращает 'Use controls to start and stop audio.'

Если вам необходимо сделать ваш код еще более устойчивым к ошибкам, вы можете рассмотреть возможность добавления проверки существования ключа в объекте на каждом шаге, чтобы избежать ошибок, если ключ не найден. Например:

function getText(selectionArray, obj) {
  for (let key of selectionArray) {
    if (obj && typeof obj === 'object' && key in obj) {
      obj = obj[key];
    } else {
      return undefined; // или можно выбросить ошибку
    }
  }
  return obj;
}

Такое обновление позволит вашей функции быть более надежной при работе с объектами, которые могут не содержать всех переданных ключей. Надеюсь, это поможет!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь