简体   繁体   中英

Javascript: Any way to shorten local usage of nested objects?

After coding a complex board game with a ton of variables, objects, and arrays, I've been told that global variables are bad, for various reasons.

One solution given was to wrap the entire javascript code in a function, making it all local. Another way to put all my variables into one object. I probably should've just gone with the first solution. But I attempted the second. As it will also make saving and loading this variable between turns via AJAX calls easier - ie I only have to save and load one object.

So my old globals were this:

let player = 'red';
let tattoos = {red: 0, blue: 0, green: 0};
let statusTrack = { 1: [1], 2: [1], 3: [2], 4: [2], 5: [4],};

And now it's like this:

let game = {
    player: 'red',
    tattoos: {red: 2, blue: 1, green: 1},
    statusTrack: { 1: [1], 2: [1], 3: [2], 4: [2], 5: [4],}
}

Which is great. Except now my actual code is very hard to read. A line that used to be this:

let stIndex = statusTrack[tattoos[player]].indexOf(player)

Is now

    let stIndex = game['statusTrack'][game['tattoos'][game['player']]].indexOf(game['player']);

So my question: Is there any way, with a library or code snippet, to convert the code I'm typing into the old format, yet still using the new "everything in one object" format for the variables?

Similar to how adding this one line:

let $ = function (id) { return document.getElementById(id); };

let's me emulate the JQuery / Sizzle selector and type $('div') instead of document.getElementById('div') ?

OR should I just go back to the old way and wrap the whole thing in a function to make it all local?

I've been told that global variables are bad, for various reasons.

While avoiding the use of global variables is good practice, it's also a very good idea to separate the handling of an app's state from the rest of the code.

One way of creating a separate state handler is with a simple class containing a constructor that initializes the state, and getters and setters for the properties.

This provides a simple way to access and modify the state, while hiding the ugly details.

The question's game object:

let game = {
    player: 'red',
    tattoos: {red: 2, blue: 1, green: 1},
    statusTrack: { 1: [1], 2: [1], 3: [2], 4: [2], 5: [4],}
}

Would look like this as a class:

 class GameState { constructor (player, tattoos, statusTrack) { this._player = player; this._tattoos = tattoos; this._statusTrack = statusTrack; } set player(p) { this._player = p; } get player() { return this._player; } get tattoo() { return this._tattoos[this._player]; } get stIndex() { const {_statusTrack: sTrack, _player: pl, _tattoos: tattoos} = this; const tat = tattoos[pl]; const activeTrack = sTrack[tat]; return activeTrack.indexOf(pl); } } const myGame = new GameState( 'red', {red: 1, blue: 1, green: 1}, { '1': [ 1 ], '2': [ 1 ], '3': [ 2 ], '4': [ 2 ], '5': [ 4 ] } ); myGame.player = 'blue'; console.log('myGame.player:', myGame.player); console.log('myGame.tattoo:', myGame.tattoo); console.log('myGame.stIndex:', myGame.stIndex);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM