首页 > 解决方案 > Javascript:有什么方法可以缩短嵌套对象的本地使用?

问题描述

在编写了包含大量变量、对象和数组的复杂棋盘游戏后,有人告诉我,由于各种原因,全局变量不好。

给出的一种解决方案是将整个 javascript 代码包装在一个函数中,使其全部本地化。另一种将我的所有变量放入一个对象的方法。我可能应该选择第一个解决方案。但我尝试了第二个。因为它还可以通过 AJAX 调用更容易地在轮次之间保存和加载这个变量 - 即我只需要保存和加载一个对象。

所以我的旧全局变量是这样的:

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

现在是这样的:

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

这是伟大的。除了现在我的实际代码很难阅读。曾经是这样的一行:

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

就是现在

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

所以我的问题是:有什么方法可以通过库或代码片段将我输入的代码转换为旧格式,但仍然使用新的“一个对象中的所有内容”格式来处理变量?

类似于如何添加这一行:

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

让我模拟JQuery/Sizzle选择器并键入$('div')而不是document.getElementById('div')?

还是我应该回到旧的方式并将整个事情包装在一个函数中以使其全部本地化?

标签: javascriptobjectvariablesglobal

解决方案


有人告诉我,由于各种原因,全局变量不好。

虽然避免使用全局变量是一种很好的做法,但将应用程序状态的处理与其余代码分开也是一个很好的主意。

创建单独的状态处理程序的一种方法是使用一个简单的类,该类包含一个初始化状态的构造函数,以及属性的 getter 和 setter。

这提供了一种访问和修改状态的简单方法,同时隐藏了丑陋的细节。

问题的game对象:

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

作为一个类看起来像这样:

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);


推荐阅读