Javascript 使用变量动态访问对象属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4244896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 11:33:50  来源:igfitidea点击:

Dynamically access object property using variable

javascriptobjectproperties

提问by RichW

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!"

回答by Jan Han?i?

There are two ways to access propertiesof an object:

两种方法可以访问对象的属性

  • Dot notation: something.bar
  • Bracket notation: something['bar']
  • 点符号: something.bar
  • 括号表示法: 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 foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected

回答by abahet

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

回答by Sonique

In javascript we can access with:

在javascript中,我们可以访问:

  • dot notation - foo.bar
  • square brackets - foo[someVar]or foo["string"]
  • 点符号 - foo.bar
  • 方括号 -foo[someVar]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

回答by zloctb

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.

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

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

这称为计算属性名称

回答by Gorka Hernandez

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:

这可以扩展到循环对象的每个属性。由于较新的 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]);
}

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'

回答by shalonteoh

You can do it like this using Lodash get

您可以使用 Lodash get 这样做

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

回答by Mr Br

UPDATED

更新

I have take comments below into consideration and agreed. Eval is to be avoided.

我已经考虑了以下评论并同意。应避免使用 Eval。

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

使用 可以轻松访问对象中的根属性obj[variable],但嵌套会使事情变得复杂。不要编写已经编写好的代码,我建议使用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 on different ways, here is link to the documentation lodash.get

Lodash get 可以以不同的方式使用,这里是文档lodash.get 的链接

回答by Rupesh Agrawal

Whenever you need to access property dynamically you have to use square bracket for accessing property not "." operator
Syntax: object[propery}

每当您需要动态访问属性时,您必须使用方括号来访问属性而不是“。” 运算符
语法: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])

回答by Luke

I came across a case where I thoughtI 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.

我遇到了一个案例,我想我想将对象属性的“地址”作为数据传递给另一个函数并填充对象(使用 AJAX),从地址数组中查找,并在该其他函数中显示。我不能在不做字符串杂技的情况下使用点符号,所以我认为传递一个数组可能会很好。无论如何,我最终做了一些不同的事情,但似乎与这篇文章有关。

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.

我希望能够传递一个数组,例如: ["audioPlayer", "controls", "stop"] 来访问语言文本,在这种情况下是 "stop"。

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)); 

回答by Hymansonkr

It gets interesting when you have to pass parameters to this function as well.

当您还必须向此函数传递参数时,这会变得很有趣。

Codejsfiddle

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