JavaScript에서 오브젝트에 구성원을 조건부로 추가하는 방법은 무엇입니까?
조건부로 멤버를 추가한 오브젝트를 만들고 싶습니다.간단한 접근법은 다음과 같습니다.
var a = {};
if (someCondition)
a.b = 5;
이제 좀 더 관용적인 코드를 쓰고 싶습니다.노력하고 있습니다.
a = {
b: (someCondition? 5 : undefined)
};
ㅇㅇㅇㅇㅇㅇㅇ.b의 멤버입니다.의 입니다.a은 " " " 입니다.undefined이것은 바람직한 결과가 아닙니다.
편리한 해결책이 있을까요?
갱신하다
저는 여러 명의 멤버로 일반적인 사건을 처리할 수 있는 해결책을 찾고 있습니다.
a = {
b: (conditionB? 5 : undefined),
c: (conditionC? 5 : undefined),
d: (conditionD? 5 : undefined),
e: (conditionE? 5 : undefined),
f: (conditionF? 5 : undefined),
g: (conditionG? 5 : undefined),
};
내 생각에는 @InspiredJW는 ES5를 사용했고 @trincot에서 지적했듯이 es6를 사용하는 것이 더 나은 접근법입니다.그러나 스프레드 연산자와 논리적 AND 단락 평가를 사용하여 설탕을 조금 더 첨가할 수 있습니다.
const a = {
...(someCondition && {b: 5})
}
const obj = {
...(condition) && {someprop: propvalue},
...otherprops
}
라이브 데모:
const obj = {
...(true) && {someprop: 42},
...(false) && {nonprop: "foo"},
...({}) && {tricky: "hello"},
}
console.log(obj);
순수 자바스크립트에서는 당신의 첫 코드 스니펫보다 더 관용적인 것은 생각할 수 없습니다.
단, jQuery 라이브러리를 사용하는 것이 불가능하지 않은 경우 $.extend()는 문서에서 설명한 바와 같이 요건을 충족해야 합니다.
정의되지 않은 속성은 복사되지 않습니다.
따라서 다음과 같이 쓸 수 있습니다.
var a = $.extend({}, {
b: conditionB ? 5 : undefined,
c: conditionC ? 5 : undefined,
// and so on...
});
기대한 (만일, 만일의 경우).conditionBfalse , , , 「 」b에는 존재하지 .a를 참조해 주세요.
다음을 권장합니다.
const a = {
...(someCondition? {b: 5}: {})
}
EcmaScript2015에서는 다음을 사용할 수 있습니다.
Object.assign(a, conditionB ? { b: 1 } : null,
conditionC ? { c: 2 } : null,
conditionD ? { d: 3 } : null);
var a, conditionB, conditionC, conditionD;
conditionC = true;
a = {};
Object.assign(a, conditionB ? { b: 1 } : null,
conditionC ? { c: 2 } : null,
conditionD ? { d: 3 } : null);
console.log(a);
비고:
Object.assign는 첫 번째 인수를 in-place로 변경하지만 갱신된 오브젝트도 반환합니다.따라서 이 메서드를 더 큰 식에서 사용하여 오브젝트를 더 조작할 수 있습니다.null할 수undefined★★★★★★★★★★★★★★★★★」{}같은 당신은 심지어 제공할 수 있다.0대신, 원시 값은 랩되어 있고 자체 열거 가능한 속성이 없기 때문입니다.
더욱 간결하게
단축할 수Jamie가 한 바와 에는 자체 가능한 없기 때문입니다(@Jamie가 지적한 대로).가변값에는 자체 열거형 속성이 없기 때문입니다).false,0,NaN,null,undefined,''( 제외):
Object.assign(a, conditionB && { b: 1 },
conditionC && { c: 2 },
conditionD && { d: 3 });
var a, conditionB, conditionC, conditionD;
conditionC = "this is truthy";
conditionD = NaN; // falsy
a = {};
Object.assign(a, conditionB && { b: 1 },
conditionC && { c: 2 },
conditionD && { d: 3 });
console.log(a);
오브젝트에 멤버를 조건부로 추가하다
const trueCondition = true;
const falseCondition = false;
const obj = {
...(trueCondition && { student: 10 }),
...(falseCondition && { teacher: 2 }),
};
// { student: 10 }
성능 테스트
클래식한 어프로치
const a = {};
if (someCondition)
a.b = 5;
대
확산 연산자 접근법
const a2 = {
...(someCondition && {b: 5})
}
결과:
기존의 어프로치가 훨씬 빠르기 때문에, 구문이 느린 것을 고려해 주세요.
Classic Condition test Classic Condition(클래식 조건) ~(); // ~234.9밀리초
Classic Condition Not Fullfuled1 mstest Classic Condition Not Fulled(); // 493.1 ms
Spread Operator Condition test 확산 연산자 " ~"); // ~2649.4ms
~0msstSpreadOperatorConditionNotFuled() // ~2278.0ms
function testSpreadOperatorConditionFulfilled() {
const value = 5;
console.time('testSpreadOperatorConditionFulfilled');
for (let i = 0; i < 200000000; i++) {
let a = {
...(value && {b: value})
};
}
console.timeEnd('testSpreadOperatorConditionFulfilled');
}
function testSpreadOperatorConditionNotFulfilled() {
const value = undefined;
console.time('testSpreadOperatorConditionNotFulfilled');
for (let i = 0; i < 200000000; i++) {
let a = {
...(value && {b: value})
};
}
console.timeEnd('testSpreadOperatorConditionNotFulfilled');
}
function testClassicConditionFulfilled() {
const value = 5;
console.time('testClassicConditionFulfilled');
for (let i = 0; i < 200000000; i++) {
let a = {};
if (value)
a.b = value;
}
console.timeEnd('testClassicConditionFulfilled');
}
function testClassicConditionNotFulfilled() {
const value = undefined;
console.time('testClassicConditionNotFulfilled');
for (let i = 0; i < 200000000; i++) {
let a = {};
if (value)
a.b = value;
}
console.timeEnd('testClassicConditionNotFulfilled');
}
testClassicConditionFulfilled(); // ~ 234.9ms
testClassicConditionNotFulfilled(); // ~493.1ms
testSpreadOperatorConditionFulfilled(); // ~2649.4ms
testSpreadOperatorConditionNotFulfilled(); // ~2278.0ms
보다 심플하게
const a = {
...(condition && {b: 1}) // if condition is true 'b' will be added.
}
확장 개체 속성을 사용하여 속성을 truthy인 경우에만 설정하는 방법은 다음과 같습니다.
[isConditionTrue() && 'propertyName']: 'propertyValue'
따라서 조건이 충족되지 않으면 기본 속성이 생성되지 않으므로 삭제할 수 있습니다.참조: http://es6-features.org/ #Computed Property Names
업데이트: Axel Rauschmayer의 블로그 기사에서 오브젝트 리터럴과 어레이 내에 엔트리를 조건부로 추가하는 방법을 따르는 것이 좋습니다(http://2ality.com/2017/04/conditional-literal-entries.html):
const arr = [
...(isConditionTrue() ? [{
key: 'value'
}] : [])
];
const obj = {
...(isConditionTrue() ? {key: 'value'} : {})
};
많은 도움이 되었습니다.
이것이 ES6에서 가장 짧은 솔루션일 것입니다.
console.log({
...true && {foo: 'bar'}
})
// Output: {foo:'bar'}
console.log({
...false && {foo: 'bar'}
})
// Output: {}
나는 이렇게 할 것이다.
var a = someCondition ? { b: 5 } : {};
되지 않은 모든 후 " "를 사용할 수 .JSON.stringify하려면:
const person = {
name: undefined,
age: 22,
height: null
}
const cleaned = JSON.parse(JSON.stringify(person));
// Contents of cleaned:
// cleaned = {
// age: 22,
// height: null
// }
오브젝트가 독립되어 있고 한 세트의 중괄호 안에 있는 것을 목표로 하고 있는 경우는, 다음과 같이 시험할 수 있습니다.
var a = new function () {
if (conditionB)
this.b = 5;
if (conditionC)
this.c = 5;
if (conditionD)
this.d = 5;
};
이것은 오랫동안 해답이 되어 왔지만, 다른 아이디어를 검토하면서, 나는 몇 가지 흥미로운 파생상품을 생각해 냈다.
동일한 속성에 정의되지 않은 값 할당 후 삭제
익명 생성자를 사용하여 개체를 만들고 맨 마지막에 제거한 동일한 더미 멤버에 정의되지 않은 멤버를 항상 할당합니다.이것에 의해, 멤버 마다 1 행(너무 복잡하지 않은 것을 희망)+ 마지막에 1 행이 추가됩니다.
var a = new function() {
this.AlwaysPresent = 1;
this[conditionA ? "a" : "undef"] = valueA;
this[conditionB ? "b" : "undef"] = valueB;
this[conditionC ? "c" : "undef"] = valueC;
this[conditionD ? "d" : "undef"] = valueD;
...
delete this.undef;
};
나는 다른 하나의 옵션을 가지고 작은 벤치마크를 만들었다.나는 어떤 물건에서 "사체 무게"를 제거하는 것을 좋아한다.보통 거짓된 값입니다.
여기 있습니다.benny★★★★
깨끗한
const clean = o => {
for (const prop in o) if (!o) delete o[prop];
}
clean({ value });
퍼지다
let a = {
...(value && {b: value})
};
한다면
let a = {};
if (value) {
a.b = value;
}
결과.
clean : 84 918 483 ops/s, ±1.16% | 51.58% slower
spread : 20 188 291 ops/s, ±0.92% | slowest, 88.49% slower
if : 175 368 197 ops/s, ±0.50% | fastest
이 서버측(jquery 없음)을 실행하는 경우는, lodash 4.3.0 을 사용할 수 있습니다.
a = _.pickBy({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined));
이것은 lodash 3.10.1을 사용하여 동작합니다.
a = _.pick({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined));
다음 코드 조각이 작동합니다.
const a = {}
const conditionB = true;
const conditionC = true;
const conditionD = true;
const conditionE = true;
const b = {
...(conditionB && { b : 5}),
...(conditionC && { c : 5}),
...(conditionD && { d : 5}),
...(conditionE && { e : 5}),
};
console.log(b);
var a = {
...(condition ? {b: 1} : '') // if condition is true 'b' will be added.
}
이 방법으로 조건에 따라 엔트리를 추가할 수 있으면 좋겠습니다.오브젝트 리터럴 내에 엔트리를 조건부로 추가하는 방법에 대한 자세한 내용을 참조하십시오.
lodash 라이브러리를 사용하면 _.omitBy를 사용할 수 있습니다.
var a = _.omitBy({
b: conditionB ? 4 : undefined,
c: conditionC ? 5 : undefined,
}, _.IsUndefined)
이 결과는 옵션인 요청이 있을 때 유용합니다.
var a = _.omitBy({
b: req.body.optionalA, //if undefined, will be removed
c: req.body.optionalB,
}, _.IsUndefined)
이것이 내가 생각해 낼 수 있는 가장 간결한 해결책이다.
var a = {};
conditionB && a.b = 5;
conditionC && a.c = 5;
conditionD && a.d = 5;
// ...
이 코드를 사용하면 이 코드를 실행할 수 있습니다.
const three = {
three: 3
}
// you can active this code, if you use object `three is null`
//const three = {}
const number = {
one: 1,
two: 2,
...(!!three && three),
four: 4
}
console.log(number);
조건부로 멤버를 추가하는 당신의 첫 번째 접근법은 완벽하다고 생각합니다.가 되고 않은 것에 별로 하지 않습니다.b- 아, 아, 아, 아! - 아, 아, 아!a 「」으로undefined 를될 정도로 간단합니다.undefined사용법을 확인하다for로 루프하다.in교환입니다.하지만 어쨌든, 여러분은 쉽게 필터링을 할 수 있는 함수를 쓸 수 있습니다.undefined회원들.
var filterUndefined = function(obj) {
var ret = {};
for (var key in obj) {
var value = obj[key];
if (obj.hasOwnProperty(key) && value !== undefined) {
ret[key] = value;
}
}
return ret;
};
var a = filterUndefined({
b: (conditionB? 5 : undefined),
c: (conditionC? 5 : undefined),
d: (conditionD? 5 : undefined),
e: (conditionE? 5 : undefined),
f: (conditionF? 5 : undefined),
g: (conditionG? 5 : undefined),
});
또,deleteoperator를 사용하여 개체를 편집합니다.
lodash 라이브러리를 사용하면 _.merge를 사용할 수 있습니다.
var a = _.merge({}, {
b: conditionB ? 4 : undefined,
c: conditionC ? 5 : undefined,
})
- 조건 B가
false& conditionC는true,그리고나서a = { c: 5 } - conditionB와 conditionC가 모두
true,그리고나서a = { b: 4, c: 5 } - conditionB와 conditionC가 모두
false,그리고나서a = {}
개체로 줄 바꿈
이런 게 좀 더 깔끔하고
const obj = {
X: 'dataX',
Y: 'dataY',
//...
}
const list = {
A: true && 'dataA',
B: false && 'dataB',
C: 'A' != 'B' && 'dataC',
D: 2000 < 100 && 'dataD',
// E: conditionE && 'dataE',
// F: conditionF && 'dataF',
//...
}
Object.keys(list).map(prop => list[prop] ? obj[prop] = list[prop] : null)
배열로 줄 바꿈
또는 Jamie Hill의 방법을 사용하고 싶고 매우 긴 조건 목록을 가지고 있다면 다음과 같이 적어야 합니다....구문을 여러 번 사용합니다.조금 더 깔끔하게 하려면 , 그것들을 배열로 감싸고 나서,reduce()하나의 물체로 돌려보낼 수 있습니다.
const obj = {
X: 'dataX',
Y: 'dataY',
//...
...[
true && { A: 'dataA'},
false && { B: 'dataB'},
'A' != 'B' && { C: 'dataC'},
2000 < 100 && { D: 'dataD'},
// conditionE && { E: 'dataE'},
// conditionF && { F: 'dataF'},
//...
].reduce(( v1, v2 ) => ({ ...v1, ...v2 }))
}
또는 사용map()기능.
const obj = {
X: 'dataX',
Y: 'dataY',
//...
}
const array = [
true && { A: 'dataA'},
false && { B: 'dataB'},
'A' != 'B' && { C: 'dataC'},
2000 < 100 && { D: 'dataD'},
// conditionE && { E: 'dataE'},
// conditionF && { F: 'dataF'},
//...
].map(val => Object.assign(obj, val))
변수 정의 기준let새 자산을 할당하면 됩니다.
let msg = {
to: "hito@email.com",
from: "hifrom@email.com",
subject: "Contact form",
};
if (file_uploaded_in_form) { // the condition goes here
msg.attachments = [ // here 'attachments' is the new property added to msg Javascript object
{
content: "attachment",
filename: "filename",
type: "mime_type",
disposition: "attachment",
},
];
}
자, 이제.msg되세요
{
to: "hito@email.com",
from: "hifrom@email.com",
subject: "Contact form",
attachments: [
{
content: "attachment",
filename: "filename",
type: "mime_type",
disposition: "attachment",
},
]
}
내 생각에 이것은 매우 간단하고 쉬운 해결책이다.
디스크립터를 추가하는 경우는, 완전하게 하기 위해서 를 사용할 수 있습니다.주의: 일부러 추가했습니다.enumerable: true그렇지 않으면 그 부동산은 에 표시되지 않을 것이다.console.log()이 접근법의 장점은 여러 개의 새로운 속성을 추가할 경우에도 사용할 수 있다는 것입니다(다만, 모든 속성은 같은 조건에 의존합니다).
const select = document.getElementById("condition");
const output = document.getElementById("output");
let a = {};
let b = {};
select.onchange = (e) => {
const condition = e.target.value === "true";
condition
? Object.defineProperty(a, "b", {
value: 5,
enumerable: true,
})
: (a = {});
condition
? Object.defineProperties(b, {
c: {
value: 5,
enumerable: true,
},
d: {
value: 6,
enumerable: true,
},
e: {
value: 7,
enumerable: true,
},
})
: (b = {});
outputSingle.innerText = JSON.stringify(a);
outputMultiple.innerText = JSON.stringify(b);
};
Condition:
<select id="condition">
<option value="false">false</option>
<option value="true">true</option>
</select>
<br/>
<br/>
Single Property: <pre id="outputSingle">{}</pre><br/>
Multiple Properties: <pre id="outputMultiple">{}</pre>
언급URL : https://stackoverflow.com/questions/11704267/in-javascript-how-to-conditionally-add-a-member-to-an-object
'source' 카테고리의 다른 글
| 이 쿼리 mysql 및 레일 5를 개선하는 방법 (0) | 2022.11.24 |
|---|---|
| 사용자 정의 변수를 사용하여 두 번째 데이터베이스에 동적으로 이름을 지정하여 해당 두 번째 데이터베이스와 함께 조인 테이블에 이름을 지정합니다. (0) | 2022.11.24 |
| Larabel에는 Mcrypt PHP 확장자가 필요합니다. (0) | 2022.11.24 |
| java의 console.log()는 무엇입니까? (0) | 2022.11.24 |
| 기본 최대 Java 힙사이즈는 어떻게 결정됩니까? (0) | 2022.11.24 |