동적으로 계산된 이름으로 개체 속성 액세스
동적 이름을 사용하여 개체의 속성에 액세스하려고 합니다.이것이 가능합니까?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
개체의 속성에 액세스하는 두 가지 방법은 다음과 같습니다.
- 표기법: 점표법기:
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)
이것이 제 해결책입니다.
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 구조 때문에 중복된 것으로 보일 수 있지만 사용 사례를 설명하는 데 도움이 됩니다.
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'
Lodashget을 사용하여 이렇게 할 수 있습니다.
_.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);
lodashget은 다양한 방법으로 사용될 수 있습니다. lodash.get 문서
속성에 동적으로 액세스하려면 대괄호를 사용합니다. []
다음과 같이:
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 is function to String() {[native code] } years"라는 메시지가 표시됩니다.는 문는입니다.agesOfUsers
는 개체이므로 다음과 같은 특정 속성을 자동으로 상속합니다..toString()
기본 Object 클래스에서 가져옵니다.여기에서 모든 개체가 상속하는 속성의 전체 목록을 확인할 수 있습니다.
솔루션
- 대신 지도 데이터 구조를 사용합니다.지도의 저장된 내용은 프로토타입 문제를 겪지 않으므로 이 문제에 대한 깨끗한 해결책을 제공합니다.
const agesOfUsers = new Map()
agesOfUsers.set('sam', 16)
agesOfUsers.set('sally', 2)
console.log(agesOfUsers.get('sam')) // 16
- 기본 프로토타입 대신 null 프로토타입이 있는 개체를 사용합니다.사용할 수 있습니다.
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
- 사용할 수 있습니다.
Object.hasOwn(yourObj, attrName)
먼저 액세스하려는 동적 키가 개체에 직접 있고 상속되지 않았는지 확인합니다(자세한 내용은 여기 참조).이 기능은 비교적 최신 기능이므로 호환성 표를 확인한 후 코드에 넣으십시오.전에Object.hasOwn(yourObj, attrName)
당신은 이와 같은 효과를 얻을 수 있을 것을 통해.Object.prototype.hasOwnProperty.call(yourObj, attrName)
때때다로을음사코볼드수있습다니를여용하▁using다▁sometimes니▁code있을 사용하는 코드가 보일 수도 있습니다.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`)
}
- 사용하려는 키가 상속된 속성의 이름이 될 수 없다는 것을 알고 있는 경우(예: 해당 키가 숫자이거나 모두 같은 접두사를 사용하는 등) 원래 솔루션을 사용을 선택할 수 있습니다.
객체 속성의 "주소"를 다른 함수에 데이터로 전달하고 객체를 채우고(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));
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
건배!
다른 사람들은 이미 '도트'와 '제곱' 구문을 언급했기 때문에 저는 비슷한 방식으로 함수에 액세스하고 매개 변수를 보내는 것에 대해 다루고 싶습니다.
코드 jfiddle
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
제가 얼마 전에 이 주제에 대해 중복되는 질문을 던졌는데, 과도한 연구 끝에, 그리고 여기 있어야 할 많은 정보가 누락된 것을 보고, 저는 제가 이 오래된 게시물에 추가할 가치가 있다고 생각합니다.
- 먼저 부동산의 가치를 얻고 동적 변수에 저장하는 몇 가지 방법이 있다는 것을 설명하고 싶습니다.IMHO의 가장 일반적이고 쉬운 방법은 다음과 같습니다.
let properyValue = element.style['enter-a-property'];
그러나 스타일시트를 통해 할당된 속성 값에는 적용되지 않기 때문에 이 경로를 거의 사용하지 않습니다.예를 들어, 저는 약간의 유사 코드로 시연해 보겠습니다.
let elem = document.getElementById('someDiv');
let cssProp = elem.style['width'];
위의 코드 예제를 사용하면, '엘렘' 변수에 저장된 div 요소의 너비 속성이 HTML 태그 내부에서 스타일이 아닌 CSS 스타일 시트에서 스타일이 지정된 경우, cssProp 변수 내부에 저장된 정의되지 않은 반환 값을 얻을 수 있습니다.정의되지 않은 값은 올바른 값을 얻으려면 CSS 스타일시트 내에 작성된 코드가 값을 얻기 위해 계산되어야 하기 때문에 발생합니다. 따라서 스타일시트 내에 있는 값의 속성 값을 계산하는 방법을 사용해야 합니다.
- 이제 getComputedStyle() 메서드를 사용합니다!
function getCssProp(){
let ele = document.getElementById("test");
let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}
W3Schools getComputedValue Doc 이것은 좋은 예를 제공하고 이것을 가지고 놀 수 있게 해줍니다. 그러나 Mozilla CSS getComputedValue Doc 링크는 getComputedValue 기능에 대해 자세히 설명하고 있으며, 이 주제에 대해 완전히 명확하지 않은 개발자 지망생이라면 누구나 읽어야 합니다.
- 참고로 getComputedValue 메서드는 설정되지 않고 가져오기만 합니다.이것은 분명히 큰 단점이지만, 표준 자바스크립트는 아니지만 CSS 스타일시트에서 가져올 뿐만 아니라 값을 설정하는 방법이 있습니다.JQuery 메서드...
$(selector).css(property,value)
...얻기도 하고, 잡기도 합니다.이것이 제가 사용하는 것입니다. 유일한 단점은 당신이 JQuery를 알게 되었다는 것입니다. 하지만 이것은 솔직히 모든 자바스크립트 개발자들이 JQuery를 배워야 하는 많은 좋은 이유 중 하나입니다. 이것은 삶을 쉽게 만들고, 표준 자바스크립트에서는 사용할 수 없는 방법을 제공합니다.이것이 누군가에게 도움이 되기를 바랍니다!
중첩 변수의 값을 설정하려는 사용자는 다음과 같이 설정할 수 있습니다.
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
괄호 표기법을 사용하여 개체의 속성에 동적으로 액세스할 수 있습니다.은 이 이것은렇이게보것입다니일.obj[yourKey]
그러나 JavaScript 개체는 동적으로 업데이트되거나 읽히도록 설계되지 않았습니다.이들은 초기화 시 정의됩니다.
으로 하고 액세스하고 key value
당신은 대신 지도를 사용해야 합니다.
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));
데모 개체 예제
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
}
getValueByDotedKeys 함수 호출
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)
저도 같은 문제에 부딪혔지만 중첩된 속성을 처리할 때 lodash 모듈이 제한됩니다.저는 재귀적인 후손 파서의 아이디어를 따라 더 일반적인 해결책을 썼습니다.이 솔루션은 다음 Gist에서 사용할 수 있습니다.
문자열을 사용하지 않고 참조로 개체 찾기 전달한 개체가 복제되었는지 확인하십시오. 이를 위해 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
}
사용할 수 있습니다.getter
개체 내부에 문제의 속성이 있는지 확인하고 없으면 창에서 속성을 가져옵니다.
const something = {
get: (n) => this.n || something.n || window[n]
};
당신은 야합다니해를 사용해야 .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)
언급URL : https://stackoverflow.com/questions/4244896/accessing-an-object-property-with-a-dynamically-computed-name
'programing' 카테고리의 다른 글
IP 주소로 사용자 위치 가져오기 (0) | 2023.06.20 |
---|---|
기존의 다른 분기에 변경 사항을 커밋하는 방법 (0) | 2023.06.20 |
iOS 앱 아이콘 설정 및 이미지 실행 방법 (0) | 2023.06.15 |
R 스크립트를 다른 스크립트에 포함(소스)하는 방법 (0) | 2023.06.15 |
Vue 2.6.0으로 업그레이드할 때 "SyntaxError: invalid range in character class"가 표시되는 이유는 무엇입니까? (0) | 2023.06.15 |