Статическая переменная в Javascript, которая устанавливается только один раз - PullRequest
2 голосов
/ 24 марта 2011

Я рвал на себе волосы, чтобы это сделать ... особенно для сценария обнаружения html5.Я хотел переменную, которая устанавливается только один раз и которая не может быть перезаписана снова.Вот оно:

var StaticConfiguration = {};
StaticConfiguration.Main = {
    _html5: null
}
StaticConfiguration.getVariable = function(name) {
    return StaticConfiguration.Main["_" + name];
}
StaticConfiguration.setVariable = function(name, value) {
    if(StaticConfiguration.Main["_" + name] == null) {
        StaticConfiguration.Main["_" + name] = value;
    }
}

Сначала я определяю глобальный объект StaticConfiguration, содержащий все эти переменные - в моем случае, просто "html5".Я установил его на нуль, так как я хочу установить его внутри приложения.Для этого я звоню

StaticConfiguration.setVariable("html5", "true");

Это установлено тогда.Если я попытаюсь установить его снова, он потерпит неудачу - конечно, поскольку _html5 больше не является нулевым.Поэтому я практически использую подчеркивание, чтобы «скрыть» статическую переменную.

Это мне очень помогает.Я надеюсь, что это хороший подход - скажите, пожалуйста, если нет :)

Ответы [ 5 ]

5 голосов
/ 24 марта 2011

Во-первых, это true, а не "true" все строки (кроме пустой строки) оцениваются как true, включая строку "false".

Во-вторых, вам действительно нужно защищать такие данные? На самом деле нет никакого способа безопасно запустить пользовательский Javascript в вашем контексте. Всегда есть способ обойти такую ​​защиту. Если нарушающий код действительно заботится, он все равно может заменить весь объект StaticConfiguration.

Код Мэтью является лучшим подходом к проблеме, но он не следует одноэлементному шаблону, а является классом, который необходимо создать. Я бы сделал это примерно так, если бы вы хотели один объект со «статическими» переменными.

StaticConfiguration = new (function()
{
  var data = {}
  this.setVariable = function(key, value)
  {
    if(typeof data[key] == 'undefined')
    {
      data[key] = value;
    }
    else
    {
      // Maybe a little error handling too...
      throw new Error("Can't set static variable that's already defined!");
    }
  };

  this.getVariable = function(key)
  {
    if (typeof data[key] == 'undefined')
    {
      // Maybe a little error handling too...
      throw new Error("Can't get static variable that isn't defined!");
    }
    else
    {
      return data[key];
    }
  };
})();

Персональный знак: я ненавижу"фигурные скобки на своих линиях", форматирующие со страстью!

1 голос
/ 24 марта 2011

Как насчет:

var StaticConfiguration = new (function()
{
  var data = {}
  this.setVariable = function(key, value)
  {
    if(typeof data[key] == 'undefined')
    {
      data[key] = value;
    }
  };

  this.getVariable = function(key)
  {
    return data[key];
  };
})();

Аналогично другому ответу, но все же допускает произвольные ключи. Это действительно личное, в отличие от подчеркивания решения.

1 голос
/ 24 марта 2011

Мне немного любопытно, почему вы думаете, что вам нужно пойти на это, чтобы защитить данные от перезаписи. Если вы обнаруживаете браузер, разве это не должно быть сделано только один раз? Если кто-то перезаписывает его неверными данными, то я предполагаю, что это будет проблемой в реализации клиента, а не в коде библиотеки - имеет ли это смысл?

В качестве примечания, я достаточно хорош в принципе KISS , особенно , когда речь идет о сценариях на стороне клиента.

1 голос
/ 24 марта 2011

Взгляните на статью Крокфорда о Private Members в JavaScript . Вы можете сделать что-то вроде этого:

var StaticConfiguration = (function() {
  var html5; /* this is private, i.e. not visible outside this anonymous function */

  return {
    getVariable: function(name) {
      ...
    },

    setVariable: function(name, value) {
      ...
    }
  };
)();
0 голосов
/ 28 февраля 2015

Я знаю, что немного опаздываю на вечеринку, но в подобных ситуациях я обычно

var data;

if (data === undefined || //or some other value you expect it to start with{
data = "new static value"
};
...