49

I'm looking for a one-liner way of checking if a key exists and if it doesn't create it.

var myObject = {};

//Anyway to do the following in a simpler fashion?

if (!('myKey' in myObject))
{
    myObject['myKey'] = {};
}
KingKongFrog
  • 13,946
  • 21
  • 75
  • 124
  • there are plenty of ways of detecting if an object has a key, as discussed [here](http://stackoverflow.com/a/1098955/6496271) – user31415 Jun 26 '16 at 00:46
  • 4
    Problem is not how to find that a key exists or not.. problem is a short one line code to add a property if it does not exist. – Zohaib Ijaz Jun 26 '16 at 00:50

10 Answers10

42

Short circuit evaluation:

!('myKey' in myObject) && (myObject.myKey = {})
undefined
  • 2,154
  • 15
  • 16
36
myObject['myKey'] = myObject['myKey'] || {};
MoustafaS
  • 1,991
  • 11
  • 20
8

Comment: I generally prefer the answers provided by @Nindaff and @MoustafaS, depending on the circumstances.

For completeness, you can create key/values, using Object.assign for any keys that did not exist. This is most useful when you have default options/settings you want to use, but allow users to overwrite via arguments. It'd look like this:

var myObject = {};
myObject = Object.assign( { 'myKey':{} }, myObject );

Here's the same thing with a little more output:

var obj = {};
console.log( 'initialized:', obj);


obj = Object.assign( {'foo':'one'}, obj );
console.log( 'foo did not exist:', obj );

obj = Object.assign( {'foo':'two'}, obj );
console.log( 'foo already exists:', obj );


delete obj.foo;
obj = Object.assign( {'foo':'two'}, obj );
console.log( 'foo did not exist:', obj );

Note: Object.assign is not available in IE, but there's a Polyfill

Community
  • 1
  • 1
BotNet
  • 2,759
  • 2
  • 16
  • 17
7

You can use the Logical nullish assignment (??=)

var test = {};
(test.hello ??= {}).world ??= "Hello doesn't exist!";
Awais Ayub
  • 389
  • 3
  • 13
5

If you want to get the value for a certain key and insert a new default value for that key if it doesn't exist and return that default value, then here you go in a single line:

> x = {}
{}
> x['k']
undefined
> x['k'] ?? (x['k'] = 23) // Insert default value for non-existent key
23
> x['k']
23
> x['z'] = 5
5
> x['z'] ?? (x['z'] = 42) // Will not insert default value because key exists
5

With the new nullish assignment operator this can be simplified to:

x['k'] ??= 23

Obviously you need to add some extra work for keys which can map to null.

Lars Blumberg
  • 19,326
  • 11
  • 90
  • 127
2

You can use hasOwnProperty or typeof for checking exits or undefine...

1

There is a designated Proxy internal type that's suitable for this task:

const myObj = new Proxy({}, {
  get (target, key) {
    return target.hasOwnProperty(key) && target[key] || (target[key] = {});
  }
});

typeof myObj.foo === 'object' && (myObj.bar.quux = 'norf') && myObj.bar.quux === 'norf';
Filip Dupanović
  • 32,650
  • 13
  • 84
  • 114
1

You can use Object.keys(), Object.hasOwnProperty()

var key = {myKey:{}}, prop = Object.keys(key).pop(), myObject = {}; if (!myObject.hasOwnProperty(prop)) {myObject[prop] = key[prop]}
console.log(myObject)
guest271314
  • 1
  • 15
  • 104
  • 177
0

JavaScript ES9 (ECMAScript 2018) introduced the spread operator:

myObject={myKey: {}, ...myObject}

myKey will be created if it doesn't already exist but wont be overwritten if it does. For example:

let obj = {a:1,b:2}

let test1 = {...obj,a:3} // == {a:3,b:2}
let test1 = {a:1,b:2,a:3} // == {a:3,b:2}

let test2 = {a:3,...obj} // == {a:1,b:2}
let test2 = {a:3,a:1,b:2} // == {a:1,b:2}
Soth
  • 2,901
  • 2
  • 27
  • 27
0

If you dont know whether or not the key of the object exists you you can do something like

object.key = (object.key || default value) operation

Example

const user = {};

user.stat = (user.stat || 0) + 1; // 1

And if you were to call this expression multiple times you'd get the expected behaviour

Example

const user = {};

user.stat = (user.stat || 0) + 1; // 1
user.stat = (user.stat || 0) + 1; // 2
user.stat = (user.stat || 0) + 1; // 3

Its effectively the same using a ternary operator like so

user.stat = user.stat ? user.stat + 1 : 0;

but more compact

iMagic
  • 1