In Python, for a dictionary d
,
d.setdefault('key', value)
sets d['key'] = value
if 'key'
was not in d
, and otherwise leaves it as it is.
Is there a clean, idiomatic way to do this on a Javascript object, or does it require an if
statement?
Actually there is no 'dictionary' type in JavaScript but we can create key-value pairs by using JavaScript Objects. Create a new JavaScript Object which will act as dictionary. Syntax: Key can be a string , integer. If you just write key1 or any number, it will treat as a string.
The setdefault() method returns the value of a key (if the key is in dictionary). If not, it inserts key with a value to the dictionary. The syntax of setdefault() is: dict.setdefault(key[, default_value])
Are there dictionaries in JavaScript? No, as of now JavaScript does not include a native “Dictionary” data type. However, Objects in JavaScript are quite flexible and can be used to create key-value pairs. These objects are quite similar to dictionaries and work alike.
The data stored in the form of key-value pairs is called an Object or a Dictionary. Objects and dictionaries are similar; the difference lies in semantics. In JavaScript, dictionaries are called objects, whereas, in languages like Python or C#, they are called dictionaries.
if (!('key' in d)) d.key = value;
or
'key' in d || (d.key = value);
(The last one uses the short-circuit behavior of conditional expressions.)
"d.key || (d.key = value)
" suggested in the other answer is buggy: if an element exists but evaluates to false
(false
, null
, 0
, -0
, ""
, undefined
, NaN
), it will be silently overwritten.
While this might be intended, it's most probably not intended for all of the aforementioned cases. So in such a case, check for the values separately:
if (!('key' in d) || d.key === null) d.key = value;
It's basically like using an if
statement, but shorter:
d.key || (d.key = value);
Or
d.key = d.key || value;
Update: as @bobtato noted, if the property is already set to the value false
it would overwrite it, so a better way would be:
!d.key && d.key !== false && (d.key = value);
Or, to do it as he suggested (just the shorthanded version):
'key' in d || (d.key = value);
// including overwriting null values:
('key' in d && d.key !== null) || (d.key = value);
Nowadays you can also do d.key ??= value
There is nothing built-in, but this function will do it:
function setDefault(obj, prop, deflt) {
return obj.hasOwnProperty(prop) ? obj[prop] : (obj[prop] = deflt);
}
If obj
will only contain non-falsy values, obj[prop] || (obj[prop] = deflt)
is a fine simple alternative (but deflt
will override anything falsy). This has the added advantage that deflt
will only get evaluated when its value is needed, so it's OK for it to be an expensive expression.
a={}
key='3'
value = 2
a[key] = a[key] == undefined ? value : a[key]
## a = {'3': 2 }
It's not recommended and is never a good idea to augment the built-in classes. Instead, it's better to create your own implementations of built-in classes, a lot like the YUI library does (YArray, etc). However, I'm going to contradict that, because I often find that implementing useful short cuts like this are a benefit to writing clean maintainable code:
if (undefined === Object.prototype.setdefault) {
Object.prototype.setdefault = function(key, def) {
if (! this.hasOwnProperty(key)) {
this[key] = def;
}
return this[key];
};
}
So let's see it in action...
var a = {};
a.setdefault('mylist', []).push(1);
a.setdefault('mylist', []).push(2);
console.log(a.mylist.toString());
1,2
As has been pointed out, it's never a good idea to employ thing = thing || defaultThing
because it only tests non-typed equality of true
, or thing == true
. As opposed to typed equality: thing === true
or thing !== undefined
. So the only way to properly code setdefault
in an inline way would be to use this snippet everywhere:
/* null == thing is equivalent to... */
if (undefined !== thing && null !== thing) {
thing = defaultThing;
}
/* ...but it's not explicit and linters don't like it! */
But as I already said, this just adds bloat to your code and is prone to errors acquired from "copy-and-paste" syndrome.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With