JS function to initialize properties
Fundamentally, not really. When you need to create a nested structure, there are no built-in ways to get around explicitly testing if the intermediate object(s) exist, and creating them if they don't.
(If you just wanted to access a possibly-existing nested element, you could use optional chaining to achieve it concisely, but nested creation is much more verbose)
There are libraries that do nested creation for you, but they ultimately implement the same sort of logic under the hood:


// Just for demonstration, I do not recommend using a library for this:

let map = {};
function newRoom(x, y) {
  _.setWith(map, [x, y, 'monsters'], {}, Object);
}
newRoom(0, 0);
console.log(map);
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"&gt;&lt;/script&gt;



One shortcut you can make in your original code is to simply check map[x] instead of comparing against undefined. You can also declare the monsters object inline when assigning the room. You should also declare the map object with const unless you're reassigning it later.
Now that logical nullish assignment exists, you could use it as well, though given how new it is, you (or others who may read the code) may not be comfortable with it, and it may look a bit confusing regardless:


const map = {};

function newRoom(x, y) {
    map[x] ??= {};
    map[x][y] = {
        monsters: {}
    };
}

/*
or
function newRoom(x, y) {
    if (!map[x]) {
      map[x] = {};
    }
    map[x][y] = {
        monsters: {}
    };
}
*/

newRoom(0, 0);
console.log(map);



I do recommend using brackets for your if blocks. They'll make it a bit easier to read and will keep you from accidentally writing on the wrong indentation level assuming that something is inside the if block, when it actually isn't.
Note that both the above code and your original code will overwrite contents of the room if it already exists in the map. Hopefully that's desirable.
There are a few alternative methods to achieve the same result that require fewer characters of code, that code golfers or minifiers could use, but they sacrifice readability and therefore aren't worth it IMO, eg:


const map = {};

function newRoom(m,n){map[m]||(map[m]={}),map[m][n]={monsters:{}}}

newRoom(0, 0);
console.log(map);



Another thing to consider - as of ES2015, Maps are more suited to dynamic properties than objects. If you want a Map, use a Map instead of an object.
function newRoom(x, y) {
    if (!map.has(x)) {
        map.set(x, new Map());
    }
    map.get(x).set('y', { monsters: {} });
}