- Start off with a 2D array filled with nulls
- For a walkable space, put a Space object into that tile slot which can hold objects lying about.
- For a visible wall (at all visible from any direction), put a Features object into that tile slot.
- Else tile remains null if it is deep in solid rock (unused).
- Check players facing, and walk a sequence of tiles in front of them, from back to front, looking at each tile (Space or Features) and rendering that feature or space at the correct scale as you go. Do the same for 1-2 parallel rows of tiles to either side of the central one -- this will give you a broader field of view. (IIRC EoB and MM had 5 total, so 2 to either side). Obviously do nothing for null tiles.
Space objects will hold various sets (8-12, usually) of object piles: 2-3 for each side of the space tile, with one shared between adjacent sides, see EoB, Dungeon Master, Captive, Knightmare for objects lying on floors.
Features objects will hold 4 Facets and a Mountable object or two, per facet (torches, plaques, or sewer grates :)
The nice thing is that because you're using JS, you can use the same empty slots in the grid for either one of the two types of objects, since JS just sees all as Object anyway. Then you'll need to use hasOwnProperty to know whether you're looking at Space or Features, per tile.
PS. Capitalised names are just my descriptors for them, they are not intended as typenames, since JS doesn't care.