使用动态计算的名称访问对象属性

发布于 2024-10-03 22:08:29 字数 187 浏览 4 评论 0原文

我正在尝试使用动态名称访问对象的属性。这可能吗?

const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"

I'm trying to access a property of an object using a dynamic name. Is this possible?

const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(22

七分※倦醒 2024-10-10 22:08:30

更新

使用 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

UPDATED

Accessing root properties in an object is easily achieved with obj[variable], but getting nested complicates things. Not to write already written code I suggest to use lodash.get.

Example

// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);

// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);

Lodash get can be used in different ways, the documentation lodash.get

ˉ厌 2024-10-10 22:08:30

要动态访问属性,只需使用方括号 []如下:

const something = { bar: "Foobar!" };
const userInput = 'bar';
console.log(something[userInput])

问题

该解决方案有一个主要问题! (我很惊讶其他答案还没有提出这个问题)。通常,您只想访问自己放入该对象的属性,而不想获取继承的属性。

这是这个问题的一个例子。这里我们有一个看似无辜的程序,但它有一个微妙的错误 - 你能发现它吗?

const agesOfUsers = { sam: 16, sally: 22 }
const username = prompt('Enter a username:')
if (agesOfUsers[username] !== undefined) {
  console.log(`${username} is ${agesOfUsers[username]} years old`)
} else {
  console.log(`${username} is not found`)
}

当提示输入用户名时,如果您提供“toString”作为用户名,则会显示以下消息:“toString 已存在 function toString() { [native code] } 岁”。问题在于 agesOfUsers 是一个对象,因此会自动从 Object 基类继承某些属性,例如 .toString()。您可以在此处查看完整列表所有对象都继承的属性。

解决方案

  1. 请改用地图数据结构。地图的存储内容不会遇到原型问题,因此它们为该问题提供了干净的解决方案。
const agesOfUsers = new Map()
agesOfUsers.set('sam', 16)
agesOfUsers.set('sally', 2)
console.log(agesOfUsers.get('sam')) // 16

  

  1. 使用具有空原型的对象,而不是默认原型。您可以使用Object.create(null)来创建这样的对象。这种类型的对象不会遇到这些原型问题,因为您已经以不继承任何内容的方式显式创建了它。
const agesOfUsers = Object.create(null)
agesOfUsers.sam = 16
agesOfUsers.sally = 22;
console.log(agesOfUsers['sam']) // 16
console.log(agesOfUsers['toString']) // undefined - toString was not inherited

  

  1. 您可以使用 Object.hasOwn(yourObj, attrName) 首先检查您要访问的动态密钥是否直接位于对象上而不是继承(了解更多此处)。这是一个相对较新的功能,因此在将其放入代码之前请检查兼容性表。在 Object.hasOwn(yourObj, attrName) 出现之前,您可以通过 Object.prototype.hasOwnProperty.call(yourObj, attrName) 实现相同的效果。有时,您可能也会看到使用 yourObj.hasOwnProperty(attrName) 的代码,有时它可以工作,但它有一些陷阱,您可以阅读有关 这里
// Try entering the property name "toString",
// you'll see it gets handled correctly.
const user = { name: 'sam', age: 16 }
const propName = prompt('Enter a property name:')
if (Object.hasOwn(user, propName)) {
  console.log(`${propName} = ${user[propName]}`)
} else {
  console.log(`${propName} is not found`)
}

  1. 如果您知道您尝试使用的密钥永远不会是继承属性的名称(例如,它们可能是数字,或者它们都具有相同的前缀等),您可以选择使用原始解决方案。

To access a property dynamically, simply use square brackets [] as follows:

const something = { bar: "Foobar!" };
const userInput = 'bar';
console.log(something[userInput])

The problem

There's a major gotchya in that solution! (I'm surprised other answers have not brought this up yet). Often you only want to access properties that you've put onto that object yourself, you don't want to grab inherited properties.

Here's an illustration of this issue. Here we have an innocent-looking program, but it has a subtle bug - can you spot it?

const agesOfUsers = { sam: 16, sally: 22 }
const username = prompt('Enter a username:')
if (agesOfUsers[username] !== undefined) {
  console.log(`${username} is ${agesOfUsers[username]} years old`)
} else {
  console.log(`${username} is not found`)
}

When prompted for a username, if you supply "toString" as a username, it'll give you the following message: "toString is function toString() { [native code] } years old". The issue is that agesOfUsers is an object, and as such, automatically inherits certain properties like .toString() from the base Object class. You can look here for a full list of properties that all objects inherit.

Solutions

  1. Use a Map data structure instead. The stored contents of a map don't suffer from prototype issues, so they provide a clean solution to this problem.

const agesOfUsers = new Map()
agesOfUsers.set('sam', 16)
agesOfUsers.set('sally', 2)
console.log(agesOfUsers.get('sam')) // 16

  

  1. Use an object with a null prototype, instead of the default prototype. You can use Object.create(null) to create such an object. This sort of object does not suffer from these prototype issues, because you've explicitly created it in a way that it does not inherit anything.

const agesOfUsers = Object.create(null)
agesOfUsers.sam = 16
agesOfUsers.sally = 22;
console.log(agesOfUsers['sam']) // 16
console.log(agesOfUsers['toString']) // undefined - toString was not inherited

  

  1. You can use Object.hasOwn(yourObj, attrName) to first check if the dynamic key you wish to access is directly on the object and not inherited (learn more here). This is a relatively newer feature, so check the compatibility tables before dropping it into your code. Before Object.hasOwn(yourObj, attrName) came around, you would achieve this same effect via Object.prototype.hasOwnProperty.call(yourObj, attrName). Sometimes, you might see code using yourObj.hasOwnProperty(attrName) too, which sometimes works but it has some pitfalls that you can read about here.

// Try entering the property name "toString",
// you'll see it gets handled correctly.
const user = { name: 'sam', age: 16 }
const propName = prompt('Enter a property name:')
if (Object.hasOwn(user, propName)) {
  console.log(`${propName} = ${user[propName]}`)
} else {
  console.log(`${propName} is not found`)
}

  1. If you know the key you're trying to use will never be the name of an inherited property (e.g. maybe they're numbers, or they all have the same prefix, etc), you can choose to use the original solution.
秋心╮凉 2024-10-10 22:08:30

我遇到过一种情况,我认为我想将对象属性的“地址”作为数据传递给另一个函数并填充该对象(使用 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)); 

I came across a case where I thought I wanted to pass the "address" of an object property as data to another function and populate the object (with AJAX), do lookup from address array, and display in that other function. I couldn't use dot notation without doing string acrobatics so I thought an array might be nice to pass instead. I ended-up doing something different anyway, but seemed related to this post.

Here's a sample of a language file object like the one I wanted data from:

const locs = {
  "audioPlayer": {
    "controls": {
      "start": "start",
      "stop": "stop"
    },
    "heading": "Use controls to start and stop audio."
  }
}

I wanted to be able to pass an array such as: ["audioPlayer", "controls", "stop"] to access the language text, "stop" in this case.

I created this little function that looks-up the "least specific" (first) address parameter, and reassigns the returned object to itself. Then it is ready to look-up the next-most-specific address parameter if one exists.

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

usage:

/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs)); 

/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs)); 
暖伴 2024-10-10 22:08:30

ES5 // 检查深度嵌套变量

这段简单的代码可以检查深度嵌套变量/值是否存在,而无需一路检查每个变量...

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

干杯!

ES5 // Check Deeply Nested Variables

This simple piece of code can check for deeply nested variable / value existence without having to check each variable along the way...

var getValue = function( s, context ){
    return Function.call( context || null, 'return ' + s )();
}

Ex. - a deeply nested array of objects:

a = [ 
    {
      b : [
          {
             a : 1,
             b : [
                 {
                    c : 1,
                    d : 2   // we want to check for this
                 }
             ]
           }
      ]
    } 
]

Instead of :

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

We can now :

if( getValue('a[0].b[0].b[0].d') == 2 ) // true

Cheers!

暮年慕年 2024-10-10 22:08:30

其他人已经提到了“点”和“方”语法,因此我想以类似的方式介绍访问函数和发送参数。

代码 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

Others have already mentioned 'dot' and 'square' syntaxes so I want to cover accessing functions and sending parameters in a similar fashion.

Code 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
静水深流 2024-10-10 22:08:30

演示对象示例

let obj = {
    name: {
        first_name: "Bugs",
        last_name: "Founder",
        role: "Programmer"
    }
}

值的

let key = "name.first_name"

用于获取函数

const getValueByDottedKeys = (obj, strKey)=>{
    let keys = strKey.split(".")
    let value = obj[keys[0]];   
    for(let i=1;i<keys.length;i++){
        value = value[keys[i]]
    }
    return value
}

getValueByDottedKeys 函数输出

value = getValueByDottedKeys(obj, key)
console.log(value)

调用

Bugs

点字符串键

const getValueByDottedKeys = (obj, strKey)=>{
    let keys = strKey.split(".")
    let value = obj[keys[0]];   
    for(let i=1;i<keys.length;i++){
        value = value[keys[i]]
    }
    return value
}

let obj = {
    name: {
        first_name: "Bugs",
        last_name: "Founder",
        role: "Programmer"
    }
}

let key = "name.first_name"

value = getValueByDottedKeys(obj, key)
console.log(value)

demo object example

let obj = {
    name: {
        first_name: "Bugs",
        last_name: "Founder",
        role: "Programmer"
    }
}

dotted string key for getting the value of

let key = "name.first_name"

Function

const getValueByDottedKeys = (obj, strKey)=>{
    let keys = strKey.split(".")
    let value = obj[keys[0]];   
    for(let i=1;i<keys.length;i++){
        value = value[keys[i]]
    }
    return value
}

Calling getValueByDottedKeys function

value = getValueByDottedKeys(obj, key)
console.log(value)

output

Bugs

const getValueByDottedKeys = (obj, strKey)=>{
    let keys = strKey.split(".")
    let value = obj[keys[0]];   
    for(let i=1;i<keys.length;i++){
        value = value[keys[i]]
    }
    return value
}

let obj = {
    name: {
        first_name: "Bugs",
        last_name: "Founder",
        role: "Programmer"
    }
}

let key = "name.first_name"

value = getValueByDottedKeys(obj, key)
console.log(value)

绝對不後悔。 2024-10-10 22:08:30

不久前,我问了一个与这个主题有点重复的问题,经过大量的研究,并看到很多应该在这里的信息缺失,我觉得我有一些有价值的东西可以添加到这篇旧文章中。

  • 首先,我想指出有多种方法可以获取属性的值并将其存储在动态变量中。恕我直言,第一个最流行且最简单的方法是:
let properyValue = element.style['enter-a-property'];

但是我很少走这条路,因为它不适用于通过样式表分配的属性值。为了给您一个例子,我将用一些伪代码进行演示。

 let elem = document.getElementById('someDiv');
 let cssProp = elem.style['width'];

使用上面的代码示例;如果存储在 'elem' 变量中的 div 元素的 width 属性在 CSS 样式表中进行样式化,而不是在其 HTML 标记内进行样式化,那么毫无疑问,您将获得存储在内部的未定义的返回值cssProp 变量的。出现未定义值是因为为了获得正确的值,需要计算 CSS 样式表内编写的代码才能获得值,因此;您必须使用一种方法来计算样式表中属性的值。

  • 从今往后,使用 getCompulatedStyle() 方法!
function getCssProp(){
  let ele = document.getElementById("test");
  let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}

W3Schools getCompulatedValue Doc 这提供了一个很好的示例,并且可以让您使用它,但是,此链接 Mozilla CSS getCompulatedValue doc 讨论了 getCompulatedValue 函数详细信息,任何对此主题不完全清楚的有抱负的开发人员都应该阅读。

  • 附带说明一下, getComputedValue 方法只能获取,不能设置。这显然是一个主要缺点,但是有一种方法可以从 CSS 样式表获取并设置值,尽管它不是标准的 Javascript。
    JQuery 方法...
$(selector).css(property,value)

...确实获取,也确实设置。这就是我使用的,唯一的缺点是你必须了解 JQuery,但这确实是每个 Javascript 开发人员应该学习 JQuery 的众多好理由之一,它让生活变得轻松,并提供了像这样的方法,不适用于标准 Javascript。
希望这对某人有帮助!

I asked a question that kinda duplicated on this topic a while back, and after excessive research, and seeing a lot of information missing that should be here, I feel I have something valuable to add to this older post.

  • Firstly I want to address that there are several ways to obtain the value of a property and store it in a dynamic Variable. The first most popular, and easiest way IMHO would be:
let properyValue = element.style['enter-a-property'];

however I rarely go this route because it doesn't work on property values assigned via style-sheets. To give you an example, I'll demonstrate with a bit of pseudo code.

 let elem = document.getElementById('someDiv');
 let cssProp = elem.style['width'];

Using the code example above; if the width property of the div element that was stored in the 'elem' variable was styled in a CSS style-sheet, and not styled inside of its HTML tag, you are without a doubt going to get a return value of undefined stored inside of the cssProp variable. The undefined value occurs because in-order to get the correct value, the code written inside a CSS Style-Sheet needs to be computed in-order to get the value, therefore; you must use a method that will compute the value of the property who's value lies within the style-sheet.

  • Henceforth the getComputedStyle() method!
function getCssProp(){
  let ele = document.getElementById("test");
  let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}

W3Schools getComputedValue Doc This gives a good example, and lets you play with it, however, this link Mozilla CSS getComputedValue doc talks about the getComputedValue function in detail, and should be read by any aspiring developer who isn't totally clear on this subject.

  • As a side note, the getComputedValue method only gets, it does not set. This, obviously is a major downside, however there is a method that gets from CSS style-sheets, as well as sets values, though it is not standard Javascript.
    The JQuery method...
$(selector).css(property,value)

...does get, and does set. It is what I use, the only downside is you got to know JQuery, but this is honestly one of the very many good reasons that every Javascript Developer should learn JQuery, it just makes life easy, and offers methods, like this one, which is not available with standard Javascript.
Hope this helps someone!!!

勿挽旧人 2024-10-10 22:08:30

对于任何想要设置嵌套变量值的人,请按以下步骤操作:

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

For anyone looking to set the value of a nested variable, here is how to do it:

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

Documentation: https://lodash.com/docs/4.17.15#set

Also, documentation if you want to get a value: https://lodash.com/docs/4.17.15#get

我不在是我 2024-10-10 22:08:30

您可以使用括号表示法动态访问对象的属性。这看起来像这样 obj[yourKey] 但是 JavaScript 对象实际上并不是为动态更新或读取而设计的。它们旨在在初始化时定义

如果您想动态分配和访问键值对,您应该使用映射。

const yourKey = 'yourKey';

// initialise it with the value
const map1 = new Map([
  ['yourKey', 'yourValue']
]);

// initialise empty then dynamically assign
const map2 = new Map();
map2.set(yourKey, 'yourValue');

console.log(map1.get(yourKey));
console.log(map2.get(yourKey));

You can do dynamically access the property of an object using the bracket notation. This would look like this obj[yourKey] however JavaScript objects are really not designed to dynamically updated or read. They are intended to be defined on initialisation.

In case you want to dynamically assign and access key value pairs you should use a map instead.

const yourKey = 'yourKey';

// initialise it with the value
const map1 = new Map([
  ['yourKey', 'yourValue']
]);

// initialise empty then dynamically assign
const map2 = new Map();
map2.set(yourKey, 'yourValue');

console.log(map1.get(yourKey));
console.log(map2.get(yourKey));

铁轨上的流浪者 2024-10-10 22:08:30

我遇到了同样的问题,但 lodash 模块在处理嵌套属性时受到限制。我按照递归下降解析器的想法编写了一个更通用的解决方案。此解决方案可在以下要点中找到:

递归下降对象取消引用

I bumped into the same problem, but the lodash module is limited when handling nested properties. I wrote a more general solution following the idea of a recursive descendent parser. This solution is available in the following Gist:

Recursive descent object dereferencing

谷夏 2024-10-10 22:08:30

这里是动态访问对象属性的一种方式,案例是根据本地存储数据访问 JSON 对象 {preferredIndustry= foodItemsFeatured}

data.foodItemsFeatured 来访问

在此处输入图像描述

let storageData = this.data; // JSON Response
let preferredData = localStorage.getItem('preferredIndustry'); //foodItemsFeatured

/* Dynamically access Object's property */
this.preferredFeaturedItems = this.data[preferredData as keyof typeof storageData];

Here is one way to access object property dynamically, Case is to access JSON Object based on localstorage data {preferredIndustry= foodItemsFeatured}

data.foodItemsFeatured to be accessed

enter image description here

let storageData = this.data; // JSON Response
let preferredData = localStorage.getItem('preferredIndustry'); //foodItemsFeatured

/* Dynamically access Object's property */
this.preferredFeaturedItems = this.data[preferredData as keyof typeof storageData];
汹涌人海 2024-10-10 22:08:30

如果您想避免使用 ES6 {[prop]:val} 方法并能够在箭头函数中使用它:

var obj = {a:1}, prop = "b", val = 2;
console.log(JSON.stringify(obj)); // {"a":1}
Object.defineProperty(obj, prop, {value:val, writable:true,enumerable:true,configurable:true});
console.log(JSON.stringify(obj)); // {"a":1,"b":2};

箭头函数:

var set = (obj, prop, val) => Object.defineProperty(obj, prop, {value:val, writable:true,enumerable:true,configurable:true});
set(obj, "c", 3);
console.log(JSON.stringify(obj));// {"a":1,"b":2, "c":3};

If you want to avoid the ES6 {[prop]:val} method and be able to use it in an arrow function:

var obj = {a:1}, prop = "b", val = 2;
console.log(JSON.stringify(obj)); // {"a":1}
Object.defineProperty(obj, prop, {value:val, writable:true,enumerable:true,configurable:true});
console.log(JSON.stringify(obj)); // {"a":1,"b":2};

Arrow function:

var set = (obj, prop, val) => Object.defineProperty(obj, prop, {value:val, writable:true,enumerable:true,configurable:true});
set(obj, "c", 3);
console.log(JSON.stringify(obj));// {"a":1,"b":2, "c":3};
海未深 2024-10-10 22:08:30

我使用下面的解决方案。看起来比reduce函数更容易阅读。

它使用括号表示法来获取属性值。它支持通过提供点('.')分隔的键来获取嵌套对象的属性值。如果对象中不存在提供的键中的属性,则返回 undefined。这是通过使用安全链接运算符“?.”来实现的。

function getPropertyValue(object, key) {
  key.split(".").forEach(token => object = object?.[token]);
  return object;
}

// Examples
const o = { a: 1, b: { c: 2, d: 3 } };
console.log(getPropertyValue(o, "a"));
console.log(getPropertyValue(o, "b"));
console.log(getPropertyValue(o, "b.c"));

// Examples where properties does not exist
console.log(getPropertyValue(o, "d"));
console.log(getPropertyValue(o, "b.a"));
console.log(getPropertyValue(o, "d.c"));
console.log(getPropertyValue(o, "b.c.d"));

I use below solution. It seems easier to read than the reduce function.

It uses the bracket notation to get the property value. It supports getting property value of nested object by providing a dot ('.') separated key. If a property in the supplied key is not present in the object, undefined is returned. This is achieved by using the safe chaining operator "?.".

function getPropertyValue(object, key) {
  key.split(".").forEach(token => object = object?.[token]);
  return object;
}

// Examples
const o = { a: 1, b: { c: 2, d: 3 } };
console.log(getPropertyValue(o, "a"));
console.log(getPropertyValue(o, "b"));
console.log(getPropertyValue(o, "b.c"));

// Examples where properties does not exist
console.log(getPropertyValue(o, "d"));
console.log(getPropertyValue(o, "b.a"));
console.log(getPropertyValue(o, "d.c"));
console.log(getPropertyValue(o, "b.c.d"));

沩ん囻菔务 2024-10-10 22:08:30

通过引用查找对象,不带字符串,
请注意,确保您传入的对象已克隆,我使用 lodash 中的cloneDeep,

如果对象看起来像

const obj = {data: ['an Object',{person: {name: {first:'nick', last:'gray'} }]

路径

const objectPath = ['data',1,'person',name','last']

,则调用下面的方法,它将按给定路径返回子对象

const child = findObjectByPath(obj, objectPath)
alert( child) // alerts "last"


const findObjectByPath = (objectIn: any, path: any[]) => {
    let obj = objectIn
    for (let i = 0; i <= path.length - 1; i++) {
        const item = path[i]
        // keep going up to the next parent
        obj = obj[item] // this is by reference
    }
    return obj
}

Finding Object by reference without, strings,
Note make sure the object you pass in is cloned , i use cloneDeep from lodash for that

if object looks like

const obj = {data: ['an Object',{person: {name: {first:'nick', last:'gray'} }]

path looks like

const objectPath = ['data',1,'person',name','last']

then call below method and it will return the sub object by path given

const child = findObjectByPath(obj, objectPath)
alert( child) // alerts "last"


const findObjectByPath = (objectIn: any, path: any[]) => {
    let obj = objectIn
    for (let i = 0; i <= path.length - 1; i++) {
        const item = path[i]
        // keep going up to the next parent
        obj = obj[item] // this is by reference
    }
    return obj
}
陌上芳菲 2024-10-10 22:08:30

您可以在 Javascript 中使用 getter

getter Docs

检查对象内部是否存在有问题的属性,
如果不存在,从窗口获取

const something = {
    get: (n) => this.n || something.n || window[n]
};

You can use getter in Javascript

getter Docs

Check inside the Object whether the property in question exists,
If it does not exist, take it from the window

const something = {
    get: (n) => this.n || something.n || window[n]
};
毁虫ゝ 2024-10-10 22:08:30

您应该使用 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)

You should use JSON.parse, take a look at 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)
回心转意 2024-10-10 22:08:29

两种方法来访问属性对象:

  • 点表示法:something.bar
  • 括号表示法:something['bar']

括号之间的值可以是任何表达式。因此,如果属性名称存储在变量中,则必须使用括号表示法:

var something = {
  bar: 'foo'
};
var foo = 'bar';

// both x = something[foo] and something[foo] = x work as expected
console.log(something[foo]);
console.log(something.bar)

There are two ways to access properties of an object:

  • Dot notation: something.bar
  • Bracket notation: something['bar']

The value between the brackets can be any expression. Therefore, if the property name is stored in a variable, you have to use bracket notation:

var something = {
  bar: 'foo'
};
var foo = 'bar';

// both x = something[foo] and something[foo] = x work as expected
console.log(something[foo]);
console.log(something.bar)

双马尾 2024-10-10 22:08:29

这是我的解决方案:

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'})

This is my solution:

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

Usage examples:

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'})
失与倦" 2024-10-10 22:08:29

在 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

In javascript we can access with:

  • dot notation - foo.bar
  • square brackets - foo[someVar] or foo["string"]

But only second case allows to access properties dynamically:

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
成熟的代价 2024-10-10 22:08:29

以下是一个 ES6 示例,说明如何使用通过连接两个字符串动态生成的属性名称来访问对象的属性。

var suffix = " name";

var person = {
    ["first" + suffix]: "Nicholas",
    ["last" + suffix]: "Zakas"
};

console.log(person["first name"]);      // "Nicholas"
console.log(person["last name"]);       // "Zakas"

这称为计算属性名称

Following is an ES6 example of how you can access the property of an object using a property name that has been dynamically generated by concatenating two strings.

var suffix = " name";

var person = {
    ["first" + suffix]: "Nicholas",
    ["last" + suffix]: "Zakas"
};

console.log(person["first name"]);      // "Nicholas"
console.log(person["last name"]);       // "Zakas"

This is called computed property names

绝影如岚 2024-10-10 22:08:29

您可以通过多种不同的方式来实现这一目标。

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'

You can achieve this in quite a few different ways.

let foo = {
    bar: 'Hello World'
};

foo.bar;
foo['bar'];

The bracket notation is specially powerful as it let's you access a property based on a variable:

let foo = {
    bar: 'Hello World'
};

let prop = 'bar';

foo[prop];

This can be extended to looping over every property of an object. This can be seem redundant due to newer JavaScript constructs such as for ... of ..., but helps illustrate a use case:

let foo = {
    bar: 'Hello World',
    baz: 'How are you doing?',
    last: 'Quite alright'
};

for (let prop in foo.getOwnPropertyNames()) {
    console.log(foo[prop]);
}

Both dot and bracket notation also work as expected for nested objects:

let foo = {
    bar: {
        baz: 'Hello World'
    }
};

foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;

Object destructuring

We could also consider object destructuring as a means to access a property in an object, but as follows:

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'
烟酉 2024-10-10 22:08:29

您可以使用 Lodash get 这样做

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

You can do it like this using Lodash get

_.get(object, 'a[0].b.c');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文