Есть ли константы в JavaScript?

1011

Есть ли способ использовать константы в JavaScript?

Если нет, то какая общая практика для указания переменных, которые используются в качестве констант?

  • 34
    Chrome позволяет использовать ключевое слово const для использования констант. например, const ASDF = "asdf" . Однако, поскольку const не совместим с несколькими браузерами, я обычно придерживаюсь декларации var .
  • 19
    try{const thing=1091;}catch(e){var thing=1091;} работает.
Показать ещё 8 комментариев
Теги:
constants

32 ответа

969
Лучший ответ

ES2015, последняя версия JavaScript, имеет понятие const:

const MY_CONSTANT = "some-value";

Это будет работать в почти во всех браузерах, кроме IE 8, 9 и 10. Некоторым может также понадобиться строгий режим.

Вы можете использовать соглашения, такие как ALL_CAPS, чтобы показать, что определенные значения не должны быть изменены, если вы не пишете код ES2015:

var MY_CONSTANT = "some-value";
  • 60
    Как насчет const x = 24;
  • 92
    Обратите внимание, что если вам не нужна кросс-браузерная совместимость (или вы программируете на стороне сервера на Rhino или Node.js), вы можете использовать ключевое слово const . В настоящее время он поддерживается всеми современными браузерами, кроме IE.
Показать ещё 10 комментариев
281

Вы пытаетесь защитить переменные от модификации? Если это так, то вы можете использовать шаблон модуля:

var CONFIG = (function() {
     var private = {
         'MY_CONST': '1',
         'ANOTHER_CONST': '2'
     };

     return {
        get: function(name) { return private[name]; }
    };
})();

alert('MY_CONST: ' + CONFIG.get('MY_CONST'));  // 1

CONFIG.MY_CONST = '2';
alert('MY_CONST: ' + CONFIG.get('MY_CONST'));  // 1

CONFIG.private.MY_CONST = '2';                 // error
alert('MY_CONST: ' + CONFIG.get('MY_CONST'));  // 1

Используя этот подход, значения не могут быть изменены. Но вы должны использовать метод get() для CONFIG: (.

Если вам не нужно строго защищать значение переменных, тогда просто сделайте так, как было предложено, и используйте соглашение ALL CAPS.

  • 12
    Обратите внимание, что вы можете просто вернуть функцию для значения CONFIG. Это спасло бы вас от вызова CONFIG.get () все время.
  • 4
    Красивое решение. Но такие вещи должны быть обернуты как библиотека, чтобы не изобретать их в любом новом проекте.
Показать ещё 7 комментариев
121

Ключевое слово const находится в проекте ECMAScript 6, но до сих пор оно только немного смахивает на поддержку браузера: http://kangax.github.io/compat-table/es6/. Синтаксис:

const CONSTANT_NAME = 0;
  • 13
    Если вы попытаетесь присвоить значение const , оно не выдаст никаких ошибок. Присвоение просто не выполняется, и константа все еще имеет свое первоначальное значение. Это главный недостаток дизайна IMHO, но пока существует четкое, согласованное соглашение об именах (такое как популярная ALL_CAPS), я не думаю, что это вызовет слишком много горя.
  • 6
    Следите за поддержкой браузера здесь: kangax.github.io/es5-compat-table/es6/#const
Показать ещё 3 комментария
60

IE поддерживает константы, вроде, например:

<script language="VBScript">
 Const IE_CONST = True
</script>
<script type="text/javascript">
 if (typeof TEST_CONST == 'undefined') {
    const IE_CONST = false;
 }
 alert(IE_CONST);
</script>
  • 49
    Мальчик, поговори о чем-то, что не является кросс-браузерным. , , Еще +1 за мысли немного нестандартно.
  • 14
    VBScript? Что это такое? ;)
Показать ещё 4 комментария
57
"use strict";

var constants = Object.freeze({
    "π": 3.141592653589793 ,
    "e": 2.718281828459045 ,
    "i": Math.sqrt(-1)
});

constants.π;        // -> 3.141592653589793
constants.π = 3;    // -> TypeError: Cannot assign to read only property 'π' …
constants.π;        // -> 3.141592653589793

delete constants.π; // -> TypeError: Unable to delete property.
constants.π;        // -> 3.141592653589793

См. Object.freeze. Вы можете использовать const, если хотите сделать ссылку constants только для чтения.

  • 2
    Следует отметить, что это работает только на IE9 + kangax.github.io/compat-table/es5 .
  • 0
    Я бы, если бы не было сломанной реализации i
Показать ещё 4 комментария
54

В ECMAScript 5 вводится Object.defineProperty:

Object.defineProperty (window,'CONSTANT',{ value : 5, writable: false });

Он поддерживается в каждом современном браузере (а также IE ≥ 9).

См. также: Object.defineProperty в ES5?

  • 1
    Стоит отметить, что это не похоже на традиционную константу. Это позволит вам только определить постоянное свойство (неконстантного объекта). Также это не генерирует ошибку и даже возвращает значение, которое вы пытаетесь установить. Это просто не записывает значение.
  • 3
    Я недавно прочитал , что попытка присвоить свойству с writable: false будет на самом деле выдаст ошибку , если код , который делает задание интерпретируется под строгим режимом ECMAscript 5 в. Еще одна причина писать 'use strict' в ваш код.
Показать ещё 1 комментарий
23

Нет, не в общем. Firefox реализует const, но я знаю, что IE этого не делает.


@John указывает на обычную практику именования для констант, которая в течение многих лет использовалась на других языках, я не вижу причин, по которым вы не мог использовать это. Конечно, это не значит, что кто-то все равно не будет писать значение переменной.:)

  • 11
    Как известно, если IE не реализует его, он может и не существовать.
  • 3
    К сожалению, и практически говоря - это правда. IE владеет огромной долей рынка. Если бы я владел бизнесом и имел веб-приложения для внутреннего использования, я бы стандартизировал FF. Я не знаю, почему так много людей заботятся о IE, это дует.
Показать ещё 3 комментария
19

Mozillas MDN Web Docs содержат хорошие примеры и пояснения о const. Выдержки:

// define MY_FAV as a constant and give it the value 7
const MY_FAV = 7;

// this will throw an error - Uncaught TypeError: Assignment to constant variable.
MY_FAV = 20;

Но грустно, что IE9/10 по-прежнему не поддерживает const. И причина, по которой это абсурдно:

Итак, что делает IE9 с константой? Так далеко, наше решение состояло в том, чтобы не поддержите его. Это еще не консенсус поскольку он никогда не был доступен на всех браузерах.

...

В конце концов, это кажется лучшим долгосрочное решение для Интернета - это оставьте это и дождитесь стандартизации для запуска их Конечно.

Они не реализуют его, потому что другие браузеры не реализовали его правильно?! Слишком бояться сделать это лучше? Определения стандартов или нет, константа является константой: устанавливается один раз, никогда не менялась.

И ко всем идеям: каждая функция может быть перезаписана (XSS и т.д.). Таким образом, нет разницы в var или function(){return}. const - единственная действительная константа.

Обновление: IE11 поддерживает const:

IE11 включает поддержку четко определенных и часто используемых функций нового стандарта ECMAScript 6, включая let, const, Map, Set и WeakMap, а также как __proto__ для улучшения взаимодействия.

  • 24
    msgstr "это никогда не было доступно во всех браузерах". Если вы не сделаете это доступным в IE, то это никогда не будет во всех браузерах.
  • 0
    стандартизация вождения не для всех;) - компании приходят и уходят снова - спасибо за цитирование шансов в лесу
Показать ещё 1 комментарий
18

В JavaScript я предпочитаю использовать функции для возврата постоянных значений.

function MY_CONSTANT() {
   return "some-value";
}


alert(MY_CONSTANT());
  • 6
    Стоит отметить, что это относится к той же проблеме, о которой говорилось в ответе @Burkes (комментарий @trinithis). `MY_CONSTANT = function () {return" some-other-value "; } ломает это. +1 хотя, достойное и быстрое решение.
  • 13
    -1. Это не имеет никакого преимущества по сравнению с var SOME_NAME = value (оно все еще изменчиво), содержит больше кода и требует объяснения.
Показать ещё 1 комментарий
16

Если вы не против использования функций:

var constant = function(val) {
   return function() {
        return val;
    }
}

Этот подход дает вам функции вместо обычных переменных, но гарантирует * что никто не может изменить значение после его установки.

a = constant(10);

a(); // 10

b = constant(20);

b(); // 20

Я лично считаю это довольно приятным, особенно после того, как привык к этому шаблону от наблюдаемых нокаутом.

* Если кто-то не переопределил функцию constant, прежде чем вы ее вызвали

  • 1
    underscore.js реализует постоянную функцию, идентичную этому коду.
  • 0
    Просто, лаконично и отвечает духу вопроса ОП. Это должно было получить больше голосов.
Показать ещё 2 комментария
16

с "новым" объектом api вы можете сделать что-то вроде этого:

var obj = {};
Object.defineProperty(obj, 'CONSTANT', {
  configurable: false
  enumerable: true,
  writable: false,
  value: "your constant value"
});

взгляните на этот на Mozilla MDN для более подробной информации. Это не первая переменная уровня, поскольку она привязана к объекту, но если у вас есть область действия, что угодно, вы можете прикрепить ее к этому. this должен работать. Так, например, если сделать это в глобальной области действия, будет объявлено псевдооднозначное значение в окне (это действительно плохая идея, вы не должны объявлять глобальные вары небрежно)

Object.defineProperty(this, 'constant', {
  enumerable: true, 
  writable: false, 
  value: 7, 
  configurable: false
});

> constant
=> 7
> constant = 5
=> 7

note: назначение вернет вам назначенное значение в консоли, но значение переменной не изменится

  • 0
    Не работает в сафари и в mozilla, если вы снова выполните оператор define - с другим значением - он переназначит значение.
  • 2
    Не «не работает в сафари», не поддерживается в сафари. Не то же самое. И он должен выдать 'Uncaught TypeError: Cannot redefine property: <имя свойства здесь>', если вы попытаетесь это сделать. либо вы делаете это неправильно, либо ваш ff неправильно это реализовал. Я предполагаю, что это смесь обоих.
11

Групповые константы в структурах, где это возможно:

Пример, в моем текущем игровом проекте, который я использовал ниже:

var CONST_WILD_TYPES = {
    REGULAR: 'REGULAR',
    EXPANDING: 'EXPANDING',
    STICKY: 'STICKY',
    SHIFTING: 'SHIFTING'
};

Назначение:

var wildType = CONST_WILD_TYPES.REGULAR;

Comparision:

if (wildType === CONST_WILD_TYPES.REGULAR) {
    // do something here
}

Совсем недавно я использую для сравнения:

switch (wildType) {
    case CONST_WILD_TYPES.REGULAR:
        // do something here
        break;
    case CONST_WILD_TYPES.EXPANDING:
        // do something here
        break;
}

IE11 с новым стандартом ES6, который имеет объявление 'const'.
Выше работает в более ранних браузерах, таких как IE8, IE9 и IE10.

10

Вы можете легко оборудовать свой script механизмом для констант, который можно установить, но не изменить. Попытка изменить их приведет к ошибке.

/* author Keith Evetts 2009 License: LGPL  
anonymous function sets up:  
global function SETCONST (String name, mixed value)  
global function CONST (String name)  
constants once set may not be altered - console error is generated  
they are retrieved as CONST(name)  
the object holding the constants is private and cannot be accessed from the outer script directly, only through the setter and getter provided  
*/

(function(){  
  var constants = {};  
  self.SETCONST = function(name,value) {  
      if (typeof name !== 'string') { throw new Error('constant name is not a string'); }  
      if (!value) { throw new Error(' no value supplied for constant ' + name); }  
      else if ((name in constants) ) { throw new Error('constant ' + name + ' is already defined'); }   
      else {   
          constants[name] = value;   
          return true;  
    }    
  };  
  self.CONST = function(name) {  
      if (typeof name !== 'string') { throw new Error('constant name is not a string'); }  
      if ( name in constants ) { return constants[name]; }    
      else { throw new Error('constant ' + name + ' has not been defined'); }  
  };  
}())  


// -------------  demo ----------------------------  
SETCONST( 'VAT', 0.175 );  
alert( CONST('VAT') );


//try to alter the value of VAT  
try{  
  SETCONST( 'VAT', 0.22 );  
} catch ( exc )  {  
   alert (exc.message);  
}  
//check old value of VAT remains  
alert( CONST('VAT') );  


// try to get at constants object directly  
constants['DODO'] = "dead bird";  // error  
8

Однако для этого не существует определенного предопределенного способа перекрестного браузера, вы можете достичь этого, контролируя область переменных, как показано на других ответах.

Но я предлагаю использовать пространство имен, чтобы отличить от других переменных. это уменьшит вероятность столкновения до минимума от других переменных.

Собственные имена, такие как

var iw_constant={
     name:'sudhanshu',
     age:'23'
     //all varibale come like this
}

поэтому при использовании будет iw_constant.name или iw_constant.age

Вы также можете заблокировать добавление нового ключа или изменение любого ключа внутри iw_constant с помощью метода Object.freeze. Однако он не поддерживается в устаревшем браузере.

ex:

Object.freeze(iw_constant);

Для более старого браузера вы можете использовать polyfill для метода замораживания.


Если вы в порядке с функцией вызова, то лучше всего использовать кросс-браузер для определения константы. Определение объекта в рамках функции самоиспускания и возврат функции get для ваших констант например:

var iw_constant= (function(){
       var allConstant={
             name:'sudhanshu',
             age:'23'
             //all varibale come like this

       };

       return function(key){
          allConstant[key];
       }
    };

//для использования значения iw_constant('name') или iw_constant('age')


** В обоих примерах вы должны быть очень осторожны с интервалом между именами, чтобы ваш объект или функция не могли быть заменены другой библиотекой. (Если сам объект или функция будет заменена, ваша целая константа будет идти)

7

Некоторое время я указывал "константы" (которые по-прежнему не были константами) в объектных литералах, переданных в выражения with(). Я думал, что это так умно. Вот пример:

with ({
    MY_CONST : 'some really important value'
}) {
    alert(MY_CONST);
}

В прошлом я также создал пространство имен CONST, где я бы поместил все мои константы. Опять же, с накладными расходами. Sheesh.

Теперь я просто делаю var MY_CONST = 'whatever'; в KISS.

  • 15
    Если есть нечто более злое, чем Eval, это определенно with .
  • 3
    Эвал очень злой! Это сгорело в моем доме один раз!
6

Мое мнение (работает только с объектами).

var constants = (function(){
  var a = 9;

  //GLOBAL CONSTANT (through "return")
  window.__defineGetter__("GCONST", function(){
    return a;
  });

  //LOCAL CONSTANT
  return {
    get CONST(){
      return a;
    }
  }
})();

constants.CONST = 8; //9
alert(constants.CONST); //9

Попробуйте! Но поймите - это объект, но не простая переменная.

Попробуйте просто:

const a = 9;
6

Забудьте IE и используйте ключевое слово const.

  • 9
    работает для меня! но потом я пишу расширение Chrome, так что я знаю, что я в здравом уме браузера ...
  • 1
    @yoyo лучшая часть о написании расширений и надстроек - без кросс-браузерной поддержки!
5

Очевидно, это указывает на необходимость стандартизованного ключевого слова cross-browser const.

Но пока:

var myconst = value;

или

Object['myconst'] = value;

Оба кажутся достаточными, и что-то еще похоже на стрельбу с помощью базуки.

  • 0
    возьмите старый добрый var myconst = value; и для отладки используйте дополнительный код отладки ... - работает как сумасшедший, пока не все браузеры поддерживают const
5

У меня тоже была проблема с этим. И после долгого времени, ища ответ и глядя на все ответы всех, я думаю, что придумал жизнеспособное решение этого.

Похоже, что большинство ответов, с которыми я сталкивался, - это использование функций для хранения констант. Как и многие пользователи форумов MANY, функции могут быть легко записаны пользователями на стороне клиента. Я был заинтригован ответом Кейта Эветта о том, что объект констант не может быть доступен снаружи, но только из функций внутри.

Итак, я придумал это решение:

Поместите все внутри анонимной функции таким образом, чтобы переменные, объекты и т.д. не могли быть изменены на стороне клиента. Также скрыть "реальные" функции, если другие функции вызовут "реальные" функции изнутри. Я также думал об использовании функций для проверки того, была ли функция изменена пользователем на стороне клиента. Если функции были изменены, измените их, используя переменные, которые "защищены" внутри и не могут быть изменены.

/*Tested in: IE 9.0.8; Firefox 14.0.1; Chrome 20.0.1180.60 m; Not Tested in Safari*/

(function(){
  /*The two functions _define and _access are from Keith Evetts 2009 License: LGPL (SETCONST and CONST).
    They're the same just as he did them, the only things I changed are the variable names and the text
    of the error messages.
  */

  //object literal to hold the constants
  var j = {};

  /*Global function _define(String h, mixed m). I named it define to mimic the way PHP 'defines' constants.
    The argument 'h' is the name of the const and has to be a string, 'm' is the value of the const and has
    to exist. If there is already a property with the same name in the object holder, then we throw an error.
    If not, we add the property and set the value to it. This is a 'hidden' function and the user doesn't
    see any of your coding call this function. You call the _makeDef() in your code and that function calls
    this function.    -    You can change the error messages to whatever you want them to say.
  */
  self._define = function(h,m) {
      if (typeof h !== 'string') { throw new Error('I don\'t know what to do.'); }
      if (!m) { throw new Error('I don\'t know what to do.'); }
      else if ((h in j) ) { throw new Error('We have a problem!'); }
      else {
          j[h] = m;
          return true;
    }
  };

  /*Global function _makeDef(String t, mixed y). I named it makeDef because we 'make the define' with this
    function. The argument 't' is the name of the const and doesn't need to be all caps because I set it
    to upper case within the function, 'y' is the value of the value of the const and has to exist. I
    make different variables to make it harder for a user to figure out whats going on. We then call the
    _define function with the two new variables. You call this function in your code to set the constant.
    You can change the error message to whatever you want it to say.
  */
  self._makeDef = function(t, y) {
      if(!y) { throw new Error('I don\'t know what to do.'); return false; }
      q = t.toUpperCase();
      w = y;
      _define(q, w);
  };

  /*Global function _getDef(String s). I named it getDef because we 'get the define' with this function. The
    argument 's' is the name of the const and doesn't need to be all capse because I set it to upper case
    within the function. I make a different variable to make it harder for a user to figure out whats going
    on. The function returns the _access function call. I pass the new variable and the original string
    along to the _access function. I do this because if a user is trying to get the value of something, if
    there is an error the argument doesn't get displayed with upper case in the error message. You call this
    function in your code to get the constant.
  */
  self._getDef = function(s) {
      z = s.toUpperCase();
      return _access(z, s);
  };

  /*Global function _access(String g, String f). I named it access because we 'access' the constant through
    this function. The argument 'g' is the name of the const and its all upper case, 'f' is also the name
    of the const, but its the original string that was passed to the _getDef() function. If there is an
    error, the original string, 'f', is displayed. This makes it harder for a user to figure out how the
    constants are being stored. If there is a property with the same name in the object holder, we return
    the constant value. If not, we check if the 'f' variable exists, if not, set it to the value of 'g' and
    throw an error. This is a 'hidden' function and the user doesn't see any of your coding call this
    function. You call the _getDef() function in your code and that function calls this function.
    You can change the error messages to whatever you want them to say.
  */
  self._access = function(g, f) {
      if (typeof g !== 'string') { throw new Error('I don\'t know what to do.'); }
      if ( g in j ) { return j[g]; }
      else { if(!f) { f = g; } throw new Error('I don\'t know what to do. I have no idea what \''+f+'\' is.'); }
  };

  /*The four variables below are private and cannot be accessed from the outside script except for the
    functions inside this anonymous function. These variables are strings of the four above functions and
    will be used by the all-dreaded eval() function to set them back to their original if any of them should
    be changed by a user trying to hack your code.
  */
  var _define_func_string = "function(h,m) {"+"      if (typeof h !== 'string') { throw new Error('I don\\'t know what to do.'); }"+"      if (!m) { throw new Error('I don\\'t know what to do.'); }"+"      else if ((h in j) ) { throw new Error('We have a problem!'); }"+"      else {"+"          j[h] = m;"+"          return true;"+"    }"+"  }";
  var _makeDef_func_string = "function(t, y) {"+"      if(!y) { throw new Error('I don\\'t know what to do.'); return false; }"+"      q = t.toUpperCase();"+"      w = y;"+"      _define(q, w);"+"  }";
  var _getDef_func_string = "function(s) {"+"      z = s.toUpperCase();"+"      return _access(z, s);"+"  }";
  var _access_func_string = "function(g, f) {"+"      if (typeof g !== 'string') { throw new Error('I don\\'t know what to do.'); }"+"      if ( g in j ) { return j[g]; }"+"      else { if(!f) { f = g; } throw new Error('I don\\'t know what to do. I have no idea what \\''+f+'\\' is.'); }"+"  }";

  /*Global function _doFunctionCheck(String u). I named it doFunctionCheck because we're 'checking the functions'
    The argument 'u' is the name of any of the four above function names you want to check. This function will
    check if a specific line of code is inside a given function. If it is, then we do nothing, if not, then
    we use the eval() function to set the function back to its original coding using the function string
    variables above. This function will also throw an error depending upon the doError variable being set to true
    This is a 'hidden' function and the user doesn't see any of your coding call this function. You call the
    doCodeCheck() function and that function calls this function.    -    You can change the error messages to
    whatever you want them to say.
  */
  self._doFunctionCheck = function(u) {
      var errMsg = 'We have a BIG problem! You\'ve changed my code.';
      var doError = true;
      d = u;
      switch(d.toLowerCase())
      {
           case "_getdef":
               if(_getDef.toString().indexOf("z = s.toUpperCase();") != -1) { /*do nothing*/ }
               else { eval("_getDef = "+_getDef_func_string); if(doError === true) { throw new Error(errMsg); } }
               break;
           case "_makedef":
               if(_makeDef.toString().indexOf("q = t.toUpperCase();") != -1) { /*do nothing*/ }
               else { eval("_makeDef = "+_makeDef_func_string); if(doError === true) { throw new Error(errMsg); } }
               break;
           case "_define":
               if(_define.toString().indexOf("else if((h in j) ) {") != -1) { /*do nothing*/ }
               else { eval("_define = "+_define_func_string); if(doError === true) { throw new Error(errMsg); } }
               break;
           case "_access":
               if(_access.toString().indexOf("else { if(!f) { f = g; }") != -1) { /*do nothing*/ }
               else { eval("_access = "+_access_func_string); if(doError === true) { throw new Error(errMsg); } }
               break;
           default:
                if(doError === true) { throw new Error('I don\'t know what to do.'); }
      }
  };

  /*Global function _doCodeCheck(String v). I named it doCodeCheck because we're 'doing a code check'. The argument
    'v' is the name of one of the first four functions in this script that you want to check. I make a different
    variable to make it harder for a user to figure out whats going on. You call this function in your code to check
    if any of the functions has been changed by the user.
  */
  self._doCodeCheck = function(v) {
      l = v;
      _doFunctionCheck(l);
  };
}())

Также кажется, что безопасность - это действительно проблема, и нет способа "спрятать" вас программирование со стороны клиента. Для меня хорошая идея - сжать свой код, чтобы кому-то, в том числе и вы, программисту, было очень сложно его прочитать и понять. Существует сайт, на который вы можете перейти: http://javascriptcompressor.com/. (Это не мой сайт, не беспокойтесь, я не рекламирую.) Это сайт, который позволит вам сжимать и обфускать код Javascript бесплатно.

  • Скопируйте весь код в приведенном выше script и вставьте его в верхнюю область textarea на странице javascriptcompressor.com.
  • Установите флажок Base62 encode, установите флажок Shrink Variables.
  • Нажмите кнопку "Сжать".
  • Вставьте и сохраните все в файле .js и добавьте его на свою страницу в начале страницы.
  • 0
    Это хорошее решение, которое можно было бы включить в библиотеку. Но мне не нравится именование ваших переменных в этом коде. Зачем отбрасывать описательные имена, такие как «имя» и «значение», которые используются в коде Кейта? Незначительная проблема, но все же.
4

Если это стоит упомянуть, вы можете определить константы в angular, используя $provide.constant()

angularApp.constant('YOUR_CONSTANT', 'value');
  • 0
    ... и вы можете использовать const в VBA ... xbrowser? ... ups ...;)
  • 0
    OP спрашивает о javascript, ответ имеет отношение к конкретной, сильно мнительной структуре JS. Практически не по теме.
Показать ещё 2 комментария
4

Хорошо, это уродливо, но это дает мне константу в Firefox и Chromium, непостоянную константу (WTF?) в Safari и Opera и переменную в IE.

Конечно, eval() является злым, но без него IE выдает ошибку, предотвращая запуск скриптов.

Safari и Opera поддерживают ключевое слово const, но вы можете изменить значение const.

В этом примере серверный код записывает JavaScript на страницу, заменяя {0} на значение.

try{
    // i can haz const?
    eval("const FOO='{0}';");
    // for reals?
    var original=FOO;
    try{
        FOO='?NO!';
    }catch(err1){
        // no err from Firefox/Chrome - fails silently
        alert('err1 '+err1);
    }
    alert('const '+FOO);
    if(FOO=='?NO!'){
        // changed in Sf/Op - set back to original value
        FOO=original;
    }
}catch(err2){
    // IE fail
    alert('err2 '+err2);
    // set var (no var keyword - Chrome/Firefox complain about redefining const)
    FOO='{0}';
    alert('var '+FOO);
}
alert('FOO '+FOO);

Для чего это полезно? Не так много, так как это не кросс-браузер. В лучшем случае, может быть, немного спокойствия, что по крайней мере некоторые браузеры не позволят закладкам или сторонним script изменять значение.

Протестировано с помощью Firefox 2, 3, 3,6, 4, Iron 8, Chrome 10, 12, Opera 11, Safari 5, IE 6, 9.

  • 3
    inconstant constant ? WTF?
  • 1
    Люблю этот код! Ужасно, черт возьми, но хороший тест для поддержки const. знак равно
Показать ещё 1 комментарий
3

Ключевое слово 'const' было предложено ранее, и теперь оно официально включено в ES6. Используя ключевое слово const, вы можете передать значение/строку, которая будет действовать как неизменяемая строка.

3

в Javascript уже существует константы. Вы определяете константу следующим образом:

const name1 = value;

Это невозможно изменить с помощью переназначения.

  • 0
    По ссылке в ответе, это экспериментальная функция и должна использоваться с осторожностью.
  • 0
    Конечно, я с тобой согласен. Но в последних версиях браузеров это работает.
3

Улучшенная версия ответа Берка, которая позволяет вам делать CONFIG.MY_CONST вместо CONFIG.get('MY_CONST').

Для этого требуется IE9 + или настоящий веб-браузер.

var CONFIG = (function() {
    var constants = {
        'MY_CONST': 1,
        'ANOTHER_CONST': 2
    };

    var result = {};
    for (var n in constants)
        if (constants.hasOwnProperty(n))
            Object.defineProperty(result, n, { value: constants[n] });

    return result;
}());

* Свойства доступны только для чтения, только если начальные значения неизменяемы.

3

Вводя константы в JavaScript, в лучшем случае является хаком.

Хорошим способом создания постоянных и общедоступных значений в JavaScript было бы объявление литерала объекта с некоторыми свойствами "только для чтения":

            my={get constant1(){return "constant 1"},
                get constant2(){return "constant 2"},
                get constant3(){return "constant 3"},
                get constantN(){return "constant N"}
                }

у вас будут все ваши константы, сгруппированные в один "мой" вспомогательный объект, где вы можете искать свои сохраненные значения или что-то еще, что вы, возможно, решили поставить там на этот счет. Теперь дайте тест, если он работает:

           my.constant1; >> "constant 1" 
           my.constant1 = "new constant 1";
           my.constant1; >> "constant 1" 

Как мы видим, свойство my.constant1 сохранил свое первоначальное значение. Вы сделали себе приятные "зеленые" временные константы...

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

В противном случае я все еще думаю, что константы для чайников. И я по-прежнему считаю, что обмен вашей большой свободой на небольшой угол обманчивой безопасности является наихудшей сделкой.

3

В JavaScript моя практика заключалась в том, чтобы избегать констант, насколько я могу, и вместо этого использовать строки. Проблемы с константами появляются, когда вы хотите выставить свои константы во внешний мир:

Например, можно реализовать следующий API дат:

date.add(5, MyModule.Date.DAY).add(12, MyModule.Date.HOUR)

Но это намного короче и естественнее просто написать:

date.add(5, "days").add(12, "hours")

Таким образом, "дни" и "часы" действительно действуют как константы, потому что вы не можете изменить извне количество секунд "часов". Но легко перезаписать MyModule.Date.HOUR.

Такой подход также поможет в отладке. Если Firebug сообщает вам action === 18, довольно сложно понять, что это значит, но когда вы видите action === "save", тогда он сразу же очищается.

  • 0
    К сожалению, довольно легко допустить орфографические ошибки - например, "Hours" вместо "hours" - но среда IDE может сообщить вам рано об этом Date.Hours не определено.
3

Я использую const вместо var в своих сценариях Greasemonkey, но это потому, что они будут запускаться только на Firefox...
Соглашение о названии может быть и в самом деле - тоже (я делаю оба!).

2

JavaScript ES6 (повторно) ввел const ключевое слово, которое поддерживается в всех основных браузеров.

Переменные, объявленные через const, не могут быть повторно объявлены или повторно назначены.

Кроме того, const ведет себя аналогично let.

Он ведет себя как и ожидалось для примитивных типов данных (Boolean, Null, Undefined, Number, String, Symbol):

const x = 1;
x = 2;
console.log(x); // 1 ...as expected, re-assigning fails

Внимание: Помните о подводных камнях относительно объектов:

const o = {x: 1};
o = {x: 2};
console.log(o); // {x: 1} ...as expected, re-assigning fails

o.x = 2;
console.log(o); // {x: 2} !!! const does not make objects immutable!

const a = [];
a = [1];
console.log(a); // 1 ...as expected, re-assigning fails

a.push(1);
console.log(a); // [1] !!! const does not make objects immutable

Если вам действительно нужен неизменный и абсолютно постоянный объект: просто используйте const ALL_CAPS, чтобы сделать ваше намерение понятным. Это хорошее соглашение для всех объявлений const в любом случае, поэтому просто положитесь на него.

  • 0
    Только из IE11 :-(
2

Другая альтернатива - это что-то вроде:

var constants = {
      MY_CONSTANT : "myconstant",
      SOMETHING_ELSE : 123
    }
  , constantMap = new function ConstantMap() {};

for(var c in constants) {
  !function(cKey) {
    Object.defineProperty(constantMap, cKey, {
      enumerable : true,
      get : function(name) { return constants[cKey]; }
    })
  }(c);
}

Тогда просто: var foo = constantMap.MY_CONSTANT

Если бы вы были constantMap.MY_CONSTANT = "bar", это не повлияло бы на то, как мы пытаемся использовать оператор присваивания с геттером, поэтому constantMap.MY_CONSTANT === "myconstant" останется истинным.

2
Ключевое слово

const доступно на языке javscript, но оно не поддерживает браузер IE. Оставьте все поддерживаемые браузеры.

2

Rhino.js реализует const в дополнение к тому, что было упомянуто выше.

0

Оформить заказ https://www.npmjs.com/package/constjs, который предоставляет три функции для создания enum, string const и bitmap. Возвращаемый результат: frozen или запечатанный, таким образом, вы можете ' t изменять/удалять свойства после их создания, вы не можете добавлять новые свойства к возвращенному результату

create Enum:

var ConstJs = require('constjs');

var Colors = ConstJs.enum("blue red");

var myColor = Colors.blue;

console.log(myColor.isBlue()); // output true 
console.log(myColor.is('blue')); // output true 
console.log(myColor.is('BLUE')); // output true 
console.log(myColor.is(0)); // output true 
console.log(myColor.is(Colors.blue)); // output true 

console.log(myColor.isRed()); // output false 
console.log(myColor.is('red')); // output false 

console.log(myColor._id); // output blue 
console.log(myColor.name()); // output blue 
console.log(myColor.toString()); // output blue 

// See how CamelCase is used to generate the isXxx() functions 
var AppMode = ConstJs.enum('SIGN_UP, LOG_IN, FORGOT_PASSWORD');
var curMode = AppMode.LOG_IN;

console.log(curMode.isLogIn()); // output true 
console.log(curMode.isSignUp()); // output false 
console.log(curMode.isForgotPassword()); // output false 

Создать строку const:

var ConstJs = require('constjs');

var Weekdays = ConstJs.const("Mon, Tue, Wed");
console.log(Weekdays); // output {Mon: 'Mon', Tue: 'Tue', Wed: 'Wed'} 

var today = Weekdays.Wed;
console.log(today); // output: 'Wed'; 

Создать растровое изображение:

var ConstJs = require('constjs');

var ColorFlags = ConstJs.bitmap("blue red");
console.log(ColorFlags.blue); // output false 

var StyleFlags = ConstJs.bitmap(true, "rustic model minimalist");
console.log(StyleFlags.rustic); // output true 

var CityFlags = ConstJs.bitmap({Chengdu: true, Sydney: false});
console.log(CityFlags.Chengdu); //output true 
console.log(CityFlags.Sydney); // output false 

var DayFlags = ConstJs.bitmap(true, {Mon: false, Tue: true});
console.log(DayFlags.Mon); // output false. Default val wont override specified val if the type is boolean  

Для получения дополнительной информации, пожалуйста, проверьте

Отказ: я автор, если этот инструмент.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню