Я хотел бы создать объект с условно добавленным членом. Простой подход:
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),
};
javascript
viebel
источник
источник
a.b
, получениеa.b
вернется вundefined
любом случае.in
оператор используется.Ответы:
В чистом Javascript я не могу придумать ничего более идиоматического, чем ваш первый фрагмент кода.
Однако если об использовании библиотеки jQuery не может быть и речи, то $ .extend () должен соответствовать вашим требованиям, потому что, как сказано в документации:
Поэтому вы можете написать:
И получить ожидаемые результаты (если
conditionB
естьfalse
, тоb
не будет существовать вa
).источник
Я думаю, что @InspiredJW сделал это с ES5, и, как указал @trincot, лучше использовать es6. Но мы можем добавить немного больше сахара, используя оператор распространения и оценку логического И короткого замыкания:
источник
Null/Undefined Are Ignored
, но оно не говорит оfalse
том, что оно игнорируется. Транспортировщики в настоящее время могут это разрешить, но соответствует ли это требованиям? Следующее должно быть,{...someCondition ? {b: 5} : null}
но не так компактно.Object.assign
и имеет более низкий приоритет, чем оператор &&. Он игнорирует значение без свойства (логическое, нулевое, неопределенное, число) и добавляет все свойства объекта после того, как...
на месте. помните, что&&
оператор возвращает правильное значение, если true, или false в противном случае. так что, еслиsomeCondition
верно,{b : 5}
будет передан к...
оператору, в результате добавления свойстваb
кa
со значением5
. issomeCondition
false,false
будет передано...
оператору. в результате ничего не добавлено. это умно Я люблю это.С EcmaScript2015 вы можете использовать
Object.assign
:Показать фрагмент кода
Некоторые замечания:
Object.assign
изменяет первый аргумент на месте, но также возвращает обновленный объект: так что вы можете использовать этот метод в большем выражении, которое дополнительно управляет объектом.null
вы могли пройтиundefined
или{}
, с тем же результатом. Вы могли бы даже предоставить0
вместо этого, потому что примитивные значения упакованы иNumber
не имеют собственных перечислимых свойств .Еще более лаконично
Принимая вторую точку дальше, вы могли бы сократить его следующим образом (как @Jamie указывал), а falsy значения не имеют собственных перечислимых свойств (
false
,0
,NaN
,null
,undefined
,''
, за исключениемdocument.all
):Показать фрагмент кода
источник
Демонстрация в реальном времени:
источник
Использование расширенного синтаксиса с логическим значением (как предлагается здесь) не является допустимым синтаксисом. Распространение можно использовать только с итерациями .
Я предлагаю следующее:
источник
{...false}
{...false}
действительный синтаксис.CopyDataProperties
выполняется со значением (false
в данном случае). Это включает в себя бокс примитива (разделы 7.3.23, 7.1.13). Ссылка на MDN упоминает это «исключение» в скобках.Как насчет использования расширенных свойств объекта и устанавливать свойство только в том случае, если оно истинно, например:
Таким образом, если условие не выполняется, оно не создает предпочтительное свойство, и, таким образом, вы можете отменить его. Смотрите: http://es6-features.org/#ComputedPropertyNames
ОБНОВЛЕНИЕ: еще лучше следовать подходу Акселя Раушмайера в его статье в блоге об условном добавлении записей внутри литералов и массивов объектов ( http://2ality.com/2017/04/conditional-literal-entries.html ):
Мне очень помогло.
источник
false
ключ. Например,{[true && 'a']: 17, [false && 'b']: 42}
это{a:17, false: 42}
...isConditionTrue() && { propertyName: 'propertyValue' }
более упрощенный,
источник
Если цель состоит в том, чтобы объект казался автономным и находился в пределах одного набора скобок, вы можете попробовать это:
источник
Если вы хотите сделать это на стороне сервера (без jquery), вы можете использовать lodash 4.3.0:
И это работает с использованием lodash 3.10.1
источник
Я надеюсь, что это очень эффективный способ добавить запись, основанную на условии. Для получения дополнительной информации о том, как условно добавлять записи внутри литералов объекта.
источник
[...condition?'':['item']]
это добавит строковый элемент в массивВы можете добавить все свои неопределенные значения без каких-либо условий, а затем использовать
JSON.stringify
для их удаления все:источник
На это уже давно дан ответ, но, глядя на другие идеи, я придумал несколько интересных производных:
Присвойте неопределенные значения тому же свойству и удалите его впоследствии
Создайте свой объект, используя анонимный конструктор, и всегда назначайте неопределенные члены тому же фиктивному члену, который вы удаляете в самом конце. Это даст вам одну строку (надеюсь, не слишком сложную) для каждого участника + 1 дополнительную строку в конце.
источник
Я бы сделал это
Редактируется с помощью однострочного кода
источник
a = undefined
return { b: undefined };
return {};
вelse
рамкахa = condition ? {b:5} : undefined;
Используя библиотеку lodash, вы можете использовать _.omitBy
Это удобно, если у вас есть необязательные запросы
источник
Определите переменную по
let
и просто назначьте новое свойствоТеперь
msg
сталоНа мой взгляд, это очень простое и легкое решение.
источник
Я думаю, что ваш первый подход к условному добавлению участников совершенно нормален. Я не совсем согласен с тем, что не хочу иметь члена
b
изa
со значениемundefined
. Достаточно просто добавитьundefined
проверку с использованиемfor
цикла сin
оператором. Но в любом случае вы можете легко написать функцию для фильтрацииundefined
членов.Вы также можете использовать
delete
оператор для редактирования объекта на месте.источник
Завернуть в объект
Что-то вроде этого немного чище
Завернуть в массив
Или, если вы хотите использовать метод Jamie Hill и иметь очень длинный список условий, вы должны написать
...
синтаксис несколько раз. Чтобы сделать его немного чище, вы можете просто обернуть их в массив, а затем использоватьreduce()
для возврата их как одного объекта.Или используя
map()
функциюисточник
Это самое краткое решение, которое я могу предложить:
источник
Используя библиотеку lodash, вы можете использовать _.merge
false
& conditionCtrue
, тоa = { c: 5 }
true
, тоa = { b: 4, c: 5 }
false
, тоa = {}
источник
lodash@^4.0.0
.undefined
включены в моем случае.