Javascript эквивалент Python dict.setdefault?
В Python для словаря d
,
d.setdefault('key', value)
устанавливает d['key'] = value
, если 'key'
не находится в d
, и в противном случае оставляет его как есть.
Есть ли чистый, идиоматический способ сделать это на объекте Javascript или требуется инструкция if
?
Ответы
Ответ 1
В основном это похоже на инструкцию if
, но короче:
d.key || (d.key = value);
или
d.key = d.key || value;
Обновление: как указано в @bobtato, если свойство уже установлено в значение false
, оно перепишет его, поэтому лучший способ:
!d.key && d.key !== false && (d.key = value);
Или, чтобы сделать это, как он предложил (только короткая версия):
'key' in d || (d.key = value);
// including overwriting null values:
('key' in d && d.key !== null) || (d.key = value);
Ответ 2
Не используйте d.key || (d.key = value)
!
Если d.key уже существует, но имеет значение, считающееся "ложным" (например, ноль или NaN или пустую строку), эта конструкция перезапишет его значением по умолчанию, которое, вероятно, будет неправильным в общем случае.
Строго эквивалент кода Python будет if (!('key' in d)) d.key = value
. Если вы хотите рассмотреть null
(или другие значения фальши) как undefined, для этого вам потребуются дополнительные тесты. Но вы должны тщательно подумать о том, что есть и не является ложным в JavaScript; например 0
является ложным, но "0"
истинно, хотя 0 == "0"
...
Ответ 3
Не рекомендуется и никогда не рекомендуется добавлять встроенные классы. Вместо этого лучше создать собственные реализации встроенных классов, что очень похоже на библиотеку YUI (YArray и т.д.). Тем не менее, я буду противоречить этому, потому что часто обнаруживаю, что реализация полезных коротких сокращений, подобных этому, является преимуществом для написания чистого поддерживаемого кода:
if (undefined === Object.prototype.setdefault) {
Object.prototype.setdefault = function(key, def) {
if (! this.hasOwnProperty(key)) {
this[key] = def;
}
return this[key];
};
}
Итак, посмотрим на это в действии...
var a = {};
a.setdefault('mylist', []).push(1);
a.setdefault('mylist', []).push(2);
console.log(a.mylist.toString());
1,2
Как уже отмечалось, никогда не рекомендуется использовать thing = thing || defaultThing
, потому что он проверяет не типизированное равенство true
или thing == true
. В отличие от типизированного равенства: thing === true
или thing !== undefined
. Таким образом, единственный способ правильно кодировать setdefault
встроенным способом - использовать этот фрагмент повсюду:
/* null == thing is equivalent to... */
if (undefined !== thing && null !== thing) {
thing = defaultThing;
}
/* ...but it not explicit and linters don't like it! */
Но, как я уже сказал, это просто добавляет вздутие к вашему коду и подвержено ошибкам, полученным от синдрома "копирование и вставка".
Ответ 4
Нет ничего встроенного, но эта функция будет делать это:
function setDefault(obj, prop, deflt) {
return obj.hasOwnProperty(prop) ? obj[prop] : (obj[prop] = deflt);
}
Если obj
будет содержать только фальшивые значения, obj[prop] || (obj[prop] = deflt)
является простой простой альтернативой (но deflt
будет отменять что-либо ложное). Это имеет дополнительное преимущество, что deflt
будет оцениваться только тогда, когда требуется его значение, поэтому для него это будет дорогостоящим выражением.
Ответ 5
a={}
key='3'
value = 2
a[key] = a[key] == undefined ? value : a[key]
## a = {'3': 2 }