JavaScript 객체 리터럴에서 키에 변수를 사용하는 방법은 무엇입니까?


406

다음은 왜 작동합니까?

<something>.stop().animate(
    { 'top' : 10 }, 10
);

작동하지 않는 반면 :

var thetop = 'top';
<something>.stop().animate(
    { thetop : 10 }, 10
);

더 명확하게하기 위해 : 현재 CSS 속성을 변수로 애니메이션 함수에 전달할 수 없습니다.



답변:


667

{ thetop : 10 }유효한 객체 리터럴입니다. 이 코드는 thetop값이 10 인 이름의 속성을 가진 객체를 만듭니다 . 다음 둘 다 동일합니다.

obj = { thetop : 10 };
obj = { "thetop" : 10 };

ES5 및 이전 버전에서는 변수를 객체 리터럴 내에서 속성 이름으로 사용할 수 없습니다. 유일한 옵션은 다음을 수행하는 것입니다.

var thetop = "top";

// create the object literal
var aniArgs = {};

// Assign the variable property name with a value of 10
aniArgs[thetop] = 10; 

// Pass the resulting object to the animate method
<something>.stop().animate(
    aniArgs, 10  
);  

ES6 ComputedPropertyName 을 객체 리터럴 문법의 일부로 정의 하므로 다음과 같은 코드를 작성할 수 있습니다.

var thetop = "top",
    obj = { [thetop]: 10 };

console.log(obj.top); // -> 10

이 새로운 구문을 각 주류 브라우저의 최신 버전에서 사용할 수 있습니다.


이해 했어요! 감사합니다! Shoudln 이것은 eval에서도 작동하지 않습니까? 나는 그것이 지금 당장 예제에서 작동하지 않는다는 것을 의미하지만, 나는 그것을 가늘게해야합니다 ... :-)
speendo

3
@Marcel : eval()동적 속성 이름의 객체 리터럴 내에서 작동하지 않으면 오류가 발생합니다. 뿐만 아니라 eval()그러한 것들에 실제로 사용되어서는 안됩니다. 의 정확하고 잘못된 사용에 대한 훌륭한 기사 있습니다 eval: blogs.msdn.com/ericlippert/archive/2003/11/01/53329.aspx은
앤디 E

2
@AndyE는 "최신 버전"과 "현재 IE TP"를 "XXX 이후 버전"또는 "2014-mm 이후"와 같이 좀 더 구체적인 시간으로 업데이트하는 것을 고려합니다. 될 것입니다.
알렉세이 Levenkov에게

1
ES6의 경우 키가 null / undefined 인 경우 속성을 제외하는 방법이 있습니까? 예를 들어,에 {[key] : "value"}키가 null의 경우, 그것은 줄 것이다 { null: "value"}나는 결과를 원하는 반면, 수,{}
wasabigeek을

훌륭한 해결책이지만, 왜 당신이 너무 많이 알고, 심지어 전체 사양을 읽더라도 포인트를 얻을 수 없었습니다 :(
hugemeow

126

함께 ECMAScript를 2015 이제 괄호 표기와 객체 선언에서 직접 할 수 있습니다 : 

var obj = {
  [key]: value
}

어디에서 key값을 반환 표현의 모든 종류 (예 : 변수)가 될 수 있습니다.

따라서 코드는 다음과 같습니다.

<something>.stop().animate({
  [thetop]: 10
}, 10)

어디 thetop키로 사용하기 전에 평가됩니다.


17

작동하지 않아야한다고 말하는 ES5 인용문

참고 : ES6에 대한 규칙이 변경되었습니다. https://stackoverflow.com/a/2274327/895245

사양 : http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.5

PropertyName :

  • 식별자 이름
  • 문자열 리터럴
  • 숫자 리터럴

[...]

프로덕션 PropertyName : IdentifierName은 다음과 같이 평가됩니다.

  1. IdentifierName과 동일한 문자 시퀀스를 포함하는 문자열 값을 반환합니다.

프로덕션 PropertyName : StringLiteral은 다음과 같이 평가됩니다.

  1. StringLiteral의 SV [문자열 값]을 반환합니다.

프로덕션 PropertyName : NumericLiteral은 다음과 같이 평가됩니다.

  1. nbr은 NumericLiteral의 값을 형성 한 결과입니다.
  2. ToString (nbr)을 반환합니다.

이것은 다음을 의미합니다.

  • { theTop : 10 } 정확히 { 'theTop' : 10 }

    PropertyName theTop입니다. IdentifierName따라서 'theTop'문자열 값인 문자열 값으로 변환됩니다 'theTop'.

  • 변수 키를 사용하여 객체 이니셜 라이저 (리터럴)를 작성할 수 없습니다.

    유일하게 세 가지 옵션은 IdentifierName(문자열 리터럴로 확장) StringLiteral, 및 NumericLiteral(또한 문자열로 확장)입니다.


3
Downvoters : 이 질문에 대한 표준을 인용 한 것은 처음 이었습니다 . 상단 답변의 ES6 인용문은 내가 대답 한 후에 편집 되었으며 해당 표준은 아직 승인되지 않았습니다. 내가 왜 다운 보트를 받고 있는지 아는 경우, 설명하고 싶습니다. 단지 배우고 싶습니다. 동료 압력 배지도받을 수 있습니다 ...
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

나는 downvote가 당신의 대답이 해결책을 제공하지 못하고 그 점에서 "유용하지 않다"고 생각합니다. 동료 압력으로 투표 :-)
Bergi

3
용기를 내 주셔서 감사합니다! :-) 그러나 나는 질문에 직접 대답했다고 생각 합니다 . Q : "다음은 왜 효과가 있습니까?" A : ES5가 그렇게 말했기 때문입니다. "어떻게해야합니까?" 암시 적입니다. 누군가 ES6 솔루션에서 편집하기 전에 표준 인용문없이 "불가능합니다"라는 가장 큰 질문을 공표 했습니까 ?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

아 맞아 나는 일반적으로 질문에 직접 대답 할 때 명확하게하기 위해 인용문에 특정 질문을 인용합니다. 표준을 인용하면 더 나은 답변을 얻을 수 있지만 현재 게시물은 질문 imo에 대답하지 않습니다. ES5에서 키를 만들 수있는 것을 말하는 것이 작동 방식 을 의미하지는 않습니다 . 확실히 thetopIdentifierName그래서, 왜 작동하지 않습니다 ? 그 질문은 여전히 ​​열려 있습니다.
Bergi

1
@Bergi 다시 설명해 주셔서 감사합니다! 더 명확하게하기 위해 업데이트했습니다. 그것은 명백했다 비록 우리가 쓸 수 있기 때문에, 나는 때문에 전에 일을하지 않았다 {a:1}.a때문에, a명확하게 식별자의 경우 변수 값을 확장하지. 그러나 그렇습니다.이 경우에는 추가 설명이 개선됩니다.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

5

다음을 사용하여 객체에 "동적"이름을 가진 속성을 추가했습니다.

var key = 'top';
$('#myElement').animate(
   (function(o) { o[key]=10; return o;})({left: 20, width: 100}),
   10
);

key 새 속성의 이름입니다.

속성의 목적은 전달 animate될 것입니다{left: 20, width: 100, top: 10}

이것은 []다른 답변에서 권장 하는 필수 표기법을 사용 하지만 코드 줄이 더 적습니다!


5

변수 주위에 대괄호를 추가하면 나에게 효과적입니다. 이 시도

var thetop = 'top';
<something>.stop().animate(
    { [thetop] : 10 }, 10
);

이전 버전의 EcmaScript에서는 작동하지 않지만 요즘에는 매우 깨끗한 접근 방식입니다.
Oliver

3

ES6과 ES5의 차이점에 대한 간단한 예를 찾을 수 없으므로 하나를 만들었습니다. 두 코드 샘플 모두 정확히 동일한 객체를 만듭니다. 그러나 ES5 예제는 IE11과 같은 오래된 브라우저에서도 작동하지만 ES6 예제는 그렇지 않습니다.

ES6

var matrix = {};
var a = 'one';
var b = 'two';
var c = 'three';
var d = 'four';

matrix[a] = {[b]: {[c]: d}};

ES5

var matrix = {};
var a = 'one';
var b = 'two';
var c = 'three';
var d = 'four';

function addObj(obj, key, value) {
  obj[key] = value;
  return obj;
}

matrix[a] = addObj({}, b, addObj({}, c, d));

2

2020 업데이트 / 예제 ...

괄호와 리터럴을 사용하는 더 복잡한 예 ... 예를 들어 vue / axios와 관련이있을 수 있습니다. 리터럴을 괄호로 묶으십시오.

[`...`]

{
    [`filter[${query.key}]`]: query.value,  // 'filter[foo]' : 'bar'
}

1

주어진 코드 :

var thetop = 'top';
<something>.stop().animate(
    { thetop : 10 }, 10
);

번역:

var thetop = 'top';
var config = { thetop : 10 }; // config.thetop = 10
<something>.stop().animate(config, 10);

보다시피, { thetop : 10 }선언은 변수를 사용하지 않습니다 thetop. 대신 이름이 키인 객체를 만듭니다 thetop. 키를 변수 값으로 사용하려면 thetop다음 과 같이 대괄호를 사용해야합니다 thetop.

var thetop = 'top';
var config = { [thetop] : 10 }; // config.top = 10
<something>.stop().animate(config, 10);

대괄호 구문은 ES6에서 도입되었습니다. 이전 버전의 JavaScript에서는 다음을 수행해야합니다.

var thetop = 'top';
var config = (
  obj = {},
  obj['' + thetop] = 10,
  obj
); // config.top = 10
<something>.stop().animate(config, 10);

1

나는 이것이 아직 게시되지 않았다고 믿을 수 없다 : 익명의 평가와 함께 화살표 표기법을 사용하십시오!

완전히 비 침습적이며 네임 스페이스를 망칠 수 없으며 한 줄만 걸립니다.

myNewObj = ((k,v)=>{o={};o[k]=v;return o;})(myKey,myValue);

데모:

새로운 {[myKey]: myValue}구문을 아직 지원하지 않는 환경 ( 예 : 명백하게; 방금 2020-01-08에 릴리스 된 웹 개발자 콘솔 —Firefox 72.0.1에서 확인했습니다.

(잠재적으로 강력하고 확장 가능한 솔루션이나 영리한 사용을 포함하는 것을 만들 수 있다고 확신 reduce하지만 그 시점에서 Object-creation을 강제로 방해하지 않고 자체 기능으로 분리하면 더 나은 서비스를 제공받을 수 있습니다 모든 인라인)


하지 영업 이익이 10 년 전 물었지만, 완성도 '술과 얼마나 보여 이후가 중요한 것은 바로 , 나는 원본 문장이 보여주지 언급 한 바와 같이 질문에 대한 답변 :

var thetop = 'top';
<something>.stop().animate(
    ((k,v)=>{o={};o[k]=v;return o;})(thetop,10), 10
);

0

이 방법으로 원하는 출력을 얻을 수도 있습니다

var jsonobj={};
var count=0;
$(document).on('click','#btnadd', function() {
    jsonobj[count]=new Array({ "1"  : $("#txtone").val()},{ "2"  : $("#txttwo").val()});
    count++;
    console.clear();
    console.log(jsonobj);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>value 1</span><input id="txtone" type="text"/>
<span>value 2</span><input id="txttwo" type="text"/>
<button id="btnadd">Add</button>


0

키를 할당하는 ES5 구현은 다음과 같습니다.

var obj = Object.create(null),
    objArgs = (
      (objArgs = {}),
      (objArgs.someKey = {
        value: 'someValue'
      }), objArgs);

Object.defineProperties(obj, objArgs);

베어 오브젝트로 변환하는 데 사용 된 스 니펫을 첨부했습니다.

var obj = {
  'key1': 'value1',
  'key2': 'value2',
  'key3': [
    'value3',
    'value4',
  ],
  'key4': {
    'key5': 'value5'
  }
}

var bareObj = function(obj) {

  var objArgs,
    bareObj = Object.create(null);

  Object.entries(obj).forEach(function([key, value]) {

    var objArgs = (
      (objArgs = {}),
      (objArgs[key] = {
        value: value
      }), objArgs);

    Object.defineProperties(bareObj, objArgs);

  });

  return {
    input: obj,
    output: bareObj
  };

}(obj);

if (!Object.entries) {
  Object.entries = function(obj){
    var arr = [];
    Object.keys(obj).forEach(function(key){
      arr.push([key, obj[key]]);
    });
    return arr;
  }
}

console(bareObj);


0

ES5에 대해 다음을 수행 할 수 있습니다.

var theTop = 'top'
<something>.stop().animate(
  JSON.parse('{"' + theTop + '":' + JSON.stringify(10) + '}'), 10
)

또는 함수로 추출하십시오.

function newObj (key, value) {
  return JSON.parse('{"' + key + '":' + JSON.stringify(value) + '}')
}

var theTop = 'top'
<something>.stop().animate(
  newObj(theTop, 10), 10
)


0

이 방법으로 할 수 있습니다 :

var thetop = 'top';
<something>.stop().animate(
    new function() {this[thetop] = 10;}, 10
);

0

다음과 같이 시도 할 수도 있습니다.

let array1 = [{
    "description": "THURSDAY",
    "count": "1",
    "date": "2019-12-05"
},
{
    "description": "WEDNESDAY",
    "count": "0",
    "date": "2019-12-04"
}]
let res = array1.map((value, index) => {
    return { [value.description]: { count: value.count, date: value.date } }
})
console.log(res);

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.