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

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

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

Chrome позволяет использовать ключевое слово const для использования констант. например const ASDF = "asdf". Однако, поскольку const не поддерживает несколько браузеров, я обычно придерживаюсь декларации var.

Jacksonkr 09.12.2011 02:22

try{const thing=1091;}catch(e){var thing=1091;} работает.

Derek 朕會功夫 22.01.2012 07:39

Дерек: не будет ли ваш try / catch ограничивать объем того, что вы объявляете блоком try / catch? Если вы неправильно оцениваете объем, то какой смысл вообще указывать const или var?

Coderer 26.03.2013 14:13

@Coderer в текущих реализациях, это будет работать, поскольку const имеет ту же область действия, что и var, и это на уровне функций, а не на уровне блоков. Если вместо этого вы будете следовать будущему стандарту ECMAScript, const будет иметь ту же область применения, что и let, а это значит, что он не будет работать.

Jasper 22.07.2013 23:27

@Coderer Неправильный язык. Переменные в javascript - это область действия функции. Это не C.

doug65536 11.09.2013 22:34

@ Джаспер Это прискорбно. Я сомневаюсь, что они действительно нарушают весь существующий код, использующий const.

doug65536 11.09.2013 22:36

@ doug65536 Это не должно нарушать весь код, использующий const. Я думаю, что по крайней мере 90% всего текущего кода все еще будет работать. Код, который может нарушить это изменение, - это код, который должен показаться сомнительным для любого, кто программировал на других языках и знает, что означает слово «область действия». К сожалению, это также означает отсутствие трюков с try, но я, честно говоря, не вижу в этом проблемы, так как странно, что синтаксическая ошибка все равно может быть обнаружена.

Jasper 12.09.2013 02:55

Хотя, если честно. Почему у нас нет const var и const let ...

cwharris 08.07.2014 22:31

const является частью стандарта Ecma 6, но очевидно, что по крайней мере один браузер реализовал его поддержку до того, как появилась спецификация для Ecma 6; см. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

slevy1 04.02.2015 10:55

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

Triynko 15.11.2016 17:37
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1 154
10
496 330
33
Перейти к ответу Данный вопрос помечен как решенный

Ответы 33

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


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

Как всем известно, если IE не реализует его, он может и не существовать.

Josh Hinman 25.09.2008 02:47

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

Jason Bunting 25.09.2008 02:50

@Rich: Кто сказал, что мое мнение было правдой? Вы сделали правильное предположение. Кроме того, насколько мне известно, то, что IE - отстой, - это факт. У вас могут быть свои собственные факты, я не говорил, что вы должны верить моим. : P Возьми ксанакс или что-то в этом роде ...

Jason Bunting 25.09.2008 03:44

@Rich B, да, это был просто глупый комментарий, и поверьте мне, я бы знал, я делаю много глупых комментариев. @Jason B. - интересно, вчера вечером я столкнулся с этой самой проблемой .. const работает в FF, но не в IE. Спасибо за разъяснение

theman_on_vista 08.04.2009 17:14

Кого волнует IE? Я не! FF, Chrome или Opera и т. д. Могут быть установлены почти на любой платформе ОС. Кроме того, продавцы компьютеров обычно знают, что старая версия IE - отстой, поэтому они часто (или даже каждый раз) устанавливают альтернативные браузеры перед продажей компьютера. Поэтому я решил, что в моем разработанном приложении совершенно не будет заботы о несовместимых браузерах: если разработчики браузеров заботятся о соблюдении стандартов, их продукт может использовать мое приложение, если нет, пользователи будут использовать другой браузер ... Я могу жить с этим; -) Но может ли Microsoft жить, теряя часть рынка? Нет, они не могут, поэтому «Они» изменят свою политику разработчиков!

willy wonka 04.01.2017 11:04
Ответ принят как подходящий

Начиная с ES2015, в JavaScript есть понятие const:

const MY_CONSTANT = "some-value";

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

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

var MY_CONSTANT = "some-value";

Обратите внимание: если вам не нужна кроссбраузерная совместимость (или вы занимаетесь программированием на стороне сервера в Rhino или Node.js), вы можете использовать ключевое слово const. В настоящее время он поддерживается всеми современными браузерами, кроме IE.

Husky 01.08.2011 23:16

В наши дни (3,5 года спустя) вы можете использовать Object.defineProperty для создания свойств только для чтения, которые также нельзя удалить. Это работает в текущей версии всех основных браузеров (кроме неправильно в IE8). См. Ответ @NotAName

Phrogz 01.06.2012 07:50

@ Dr.Zim: согласно стандартам кодирования вы никогда не должны использовать ключевое слово const, так как оно не поддерживается в Internet Explorer. Ссылка: google-styleguide.googlecode.com/svn/trunk/…

Amyth 22.05.2013 17:00

Итак, что теперь - разрешено использование const или нет?

dngfng 31.10.2013 17:30

@Amyth Это бесполезно. Это стиль гид, предложенный единственным поставщиком. В соответствии с указанием Хаски выше, совместимость с IE совершенно не важна при написании серверного JS.

aendrew 06.11.2013 15:40

@dngfng 6 лет спустя const поддерживается всеми браузерами, кроме IE10 и более ранних.

David 08.10.2014 00:12

Поскольку этот ответ по-прежнему высоко ценится Google в 2015 году, следует сказать, что теперь он устарел. Ключевое слово const теперь официально является частью языка и поддерживается всеми браузерами. По данным statcounter.com, лишь несколько процентов интернет-пользователей все еще используют старые версии браузеров, не поддерживающие const.

tristan 06.09.2015 19:50

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

sam 02.07.2017 21:10

Это ответ наивный как constпредотвращает только от переназначения! Вы можете сделать что-то вроде: const x = {a: 1};, а затем x.a = 2; Осторожно! Для постоянного постоянного использования: const x = Object.freeze({a: 1});

iaforek 27.09.2017 00:45

Почему вы сравниваете IE с браузерами? они не одного типа

Jafar Akhondali 13.10.2017 13:20

@ Black-Hole IE == otherBrowser, даже если IE! == otherBrowser

Kartik Chugh 14.08.2018 22:02

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

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

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

Раньше я также создавал пространство имен CONST, в которое помещал все свои константы. Опять же, с накладными расходами. Блин.

Теперь я просто делаю var MY_CONST = 'whatever'; для ЦЕЛОВАТЬ.

Если есть что-то более злое, чем злое, то это определенно with.

NikiC 01.05.2011 18:51

eval очень злой! Однажды она сожгла мой дом!

W3Geek 03.01.2014 00:14

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

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 :(.

Если вам не нужно строго защищать значение переменных, просто сделайте то, что предлагается, и используйте соглашение ВСЕ ЗАГЛАВНЫЕ буквы.

Обратите внимание, что вы можете просто вернуть функцию для значения CONFIG. Это избавит вас от постоянного вызова CONFIG.get ().

Mathew Byrne 25.09.2008 10:58

Красивое решение. Но такие вещи следует оформить в виде библиотеки, чтобы не изобретать их заново в каком-либо новом проекте.

andrii 08.03.2009 12:53

CONFIG.get = someNewFunctionThatBreaksTheCode ... В общем, вы абсолютно не можете применять константы в JS (без ключевого слова const). Единственное, что вы можете сделать, это ограничить видимость.

Thomas Eding 12.01.2010 02:20

Я верю, что private - это будущее зарезервированное слово в JavaScript, я бы не стал его использовать на вашем месте.

Zaq 05.08.2012 20:49

Это тоже шаблон реестра.

user656925 16.08.2012 01:14

@MathewByrne И еще одно преимущество этого; вы не можете сломать его, назначив другую функцию вместо get, как сказал Томас Эдинг ...;) (Если, конечно, вы не назначаете функцию через config). Это красивое и удобочитаемое решение, которое будет работать в большинстве случаев.

W3Geek 02.01.2014 20:17

Спасибо за обращение к контексту проблемы. Вы также показали нам, как использовать частные переменные и получать к ним доступ извне.

kta 16.01.2015 15:41

Этот Только защищает от модификации для примитивные типы данных. Если 'MY_CONST': [1,2,3], вы все равно можете сделать CONFIG.get('MY_CONST').push(4).

le_m 13.06.2016 05:52

Это также упускает одно преимущество констант - если есть опечатка, код не сломается. Таким образом, CONFIG.get('MY_CONTS') вернет undefined, а не ошибку, что затруднит выявление опечатки.

Malvineous 19.07.2016 10:27

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

const CONSTANT_NAME = 0;

Если вы попытаетесь присвоить значение const, он не выдаст никаких ошибок. Присваивание просто не выполняется, и константа все еще имеет свое исходное значение. Это серьезный недостаток дизайна. ИМХО, но пока существует четкое, последовательное соглашение об именах (например, популярное ALL_CAPS), я не думаю, что это вызовет слишком много проблем.

MatrixFrog 30.06.2010 01:54

Следите за поддержкой браузера здесь: kangax.github.io/es5-compat-table/es6/#const

Mark McDonald 04.05.2013 09:18

Назначение @MatrixFrog вызовет ошибку с 'use strict'.

sam 13.03.2015 20:19

Следует ли определять константы в ALL CAPS?

Lewis 08.08.2015 09:53

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

Bill the Lizard 08.08.2015 13:42

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>

Боже, поговорим о том, что не является кроссбраузерным . . Тем не менее +1 за нестандартное мышление.

Tom 26.10.2009 22:36

VBScript? Это что? ;)

tybro0103 27.09.2013 08:06

Обычно я голосую за общий вопрос, связанный с кроссбраузерностью, с конкретным ответом IE. Потому что я ненавижу людей, которые думают, что реализация javascript IE - «Единственная», а другие просто игнорируются. Кто, кстати, использует другие браузеры, кроме IE?

Ant 03.10.2013 00:54

@Cooluhuru этот скрипт, похоже, обрабатывает как браузеры IE (с использованием VBScript), так и браузеры, отличные от IE (с использованием JavaScript const). Вы можете объяснить, что с этим не так?

Andrew Grimm 13.07.2016 10:47

Мне все еще трудно принять, что константы можно изменять.

Norbert Norbertson 30.01.2018 18:46

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

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


alert(MY_CONSTANT());

Стоит отметить, что это относится к той же проблеме, что и в ответе @Burkes (комментарий @trinithis). `MY_CONSTANT = function () {вернуть" какое-то другое значение "; } ломает это. +1 впрочем, достойное и быстрое решение.

Patrick M 13.07.2012 16:21

-1. Это не имеет преимуществ по сравнению с var SOME_NAME = value (оно все еще изменяемо), это больше кода и требует объяснения.

mikemaccana 01.03.2013 19:39

@PatrickM, хотя это правда, что вы можете изменять такие псевдоконстанты на других языках, например, C, на котором вы изменяете константы не должен быть в состоянии, вы все равно можете сделать это, например, указатели. Итак, пока вы используете какой-то подход, который, по крайней мере, предлагает, что это константа, это нормально, imo.

rev 28.07.2014 15:43

ECMAScript 5 вводит Object.defineProperty:

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

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

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

Стоит отметить, что это не похоже на традиционную константу. Это позволит вам определить только постоянное свойство (непостоянного объекта). Также это не вызывает ошибки и даже возвращает значение, которое вы пытаетесь установить. Он просто не записывает значение.

Cory Gross 07.07.2013 18:03

Недавно я прочитал, что попытка присвоения свойству с помощью writable: falseволя фактически вызывает ошибку, если код, выполняющий присвоение, интерпретируется в строгом режиме ECMAScript 5. Еще одна причина написать 'use strict' в вашем коде.

Cory Gross 22.07.2013 03:10

Фактически вы можете опустить writable: false, поскольку это дефолт.

sam 05.05.2014 03:39

В 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", все сразу становится ясно.

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

le_m 13.06.2016 06:09

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

/* 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  

Веб-документы Mozillas MDN содержат хорошие примеры и пояснения по 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. И причина это абсурдный:

So, what is IE9 doing with const? So far, our decision has been to not support it. It isn’t yet a consensus feature as it has never been available on all browsers.

...

In the end, it seems like the best long term solution for the web is to leave it out and to wait for standardization processes to run their course.

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

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

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

IE11 includes support for the well-defined and commonly used features of the emerging ECMAScript 6 standard including let, const, Map, Set, and WeakMap, as well as __proto__ for improved interoperability.

«он никогда не был доступен во всех браузерах». Если вы не сделаете его доступным в IE, он никогда не будет доступен во всех браузерах.

km1 15.08.2012 18:11

стандартизация вождения не для всех;) - компании приходят и уходят снова - спасибо, что указали разногласия в лесу

Quicker 11.03.2016 00:22

еще один по этому поводу: VBA еще не является консенсусной функцией во всех браузерах, а MS поддерживает const в VBA - это мастерство распределения бюджетов на разработку;)

Quicker 11.03.2016 00:34

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

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

Safari и Opera поддерживают ключевое слово 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);

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

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

Люблю этот код! Как ни крути, но хороший тест на поддержку констант. знак равно

Stein G. Strindhaug 13.12.2011 12:23

несколько забавно, эй - сколько строк можно ввести, чтобы объявить константу?

Quicker 11.03.2016 00:27

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

работает для меня! но потом я пишу расширение для Chrome, так что я знаю, что использую нормальный браузер ...

yoyo 11.11.2011 20:50

@yoyo лучшая часть написания расширений и надстроек - кроссбраузерной поддержки нет!

Ian 17.08.2014 20:10

@Ian Добро пожаловать в 2019 год, кроссбраузерность практически исчезла :)

Fusseldieb 03.06.2019 15:21

Введение констант в JavaScript - в лучшем случае хитрость.

Хороший способ сделать постоянные и глобально доступные значения в JavaScript - объявить литерал объекта с некоторыми свойствами, доступными только для чтения, наподобие этого:

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

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

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

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

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

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

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

Кажется, что большинство ответов, с которыми я столкнулся, связаны с использованием функций для хранения констант. Как пишут многие пользователи МНОГИХ форумов, функции могут быть легко переписаны пользователями на стороне клиента. Меня заинтриговал ответ Кита Эветтса о том, что к объекту констант нельзя получить доступ извне, а только из внутренних функций.

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

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

/*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.

  1. Скопируйте весь код из приведенного выше скрипта и вставьте его в верхнее текстовое поле на странице javascriptcompressor.com.
  2. Установите флажок Кодировать Base62, установите флажок Сжать переменные.
  3. Нажмите кнопку «Сжать».
  4. Вставьте и сохраните все это в файле .js и добавьте его на свою страницу в заголовке страницы.

Это хорошее решение, которое можно было бы красиво оформить в виде библиотеки для включения. Но мне не нравится именование ваших переменных в этом коде. Зачем отбрасывать описательные имена, такие как «имя» и «значение», используемые в коде Кита? Мелкая проблема, но все же.

Cordle 03.06.2014 18:24

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

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;

с "новым" 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

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

Не работает в Safari, а в Mozilla, если вы снова выполните оператор define - с другим значением - он изменит значение.

Akshay 11.12.2013 12:32

Не «не работает в сафари», не поддержанный в сафари. Не то же самое. И он должен выдать 'Uncaught TypeError: Cannot redefine property: <property name here>', если вы попробуете это. либо вы делаете это неправильно, либо ваш ff неправильно его реализовал. Думаю, это сочетание того и другого.

tenshou 18.12.2013 01:48

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

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

Но сейчас:

var myconst = value;

или же

Object['myconst'] = value;

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

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

Quicker 11.03.2016 00:28

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

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

Правильное пространство имен, например

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

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

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

бывший:

Object.freeze(iw_constant);

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


Если вас устраивает вызывающая функция, лучше всего использовать кроссбраузерный способ определения константы. Определение области вашего объекта внутри самоисполняющейся функции и возврат функции 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')


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

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

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

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

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

a = constant(10);

a(); // 10

b = constant(20);

b(); // 20

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

SB666

underscore.js реализует постоянную функцию, идентичную этому коду.

Upperstage 18.06.2014 21:13

Просто, лаконично и отвечает духу вопроса ОП. Это должно было получить больше голосов.

Mac 11.11.2014 22:41

У меня это никогда не работало. Несмотря на то, что закрытие делает его неизменным, переменную, которую вы ему назначаете, все равно можно перезаписать. Пример: a = constant(10); a(10); // 10, за которым следует a = constant(25); a(); //25, ошибок или предупреждений нет, нет никаких указаний на то, что ваша константа была нарушена.

Patrick M 21.09.2015 22:46

Если я переназначу значение a, оно изменится на новое значение

Saurabh Sharma 05.10.2016 09:05

"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 доступной только для чтения.

Следует упомянуть, что это работает только в IE9 + kangax.github.io/compat-table/es5.

Cordle 03.06.2014 18:27

Я бы, если бы не сломанная реализация i

Alnitak 16.01.2015 15:43

Примечание: это ведет себя аналогично объявлению ES6 const, например. свойства нельзя повторно объявить или переназначить, но если они имеют тип данных object, они могут быть изменены.

le_m 13.06.2016 05:56

Именно то, что я искал. Вы также можете использовать const constants вместо var constants, чтобы предотвратить переназначение переменной.

Jarett Millard 27.04.2017 00:04

См., Например, морозильная камера для рекурсивного замораживания.

sam 08.09.2017 00:26

Использование комбинации const и Object.freeze() в основном эквивалентно константе из других языков программирования.

iaforek 27.09.2017 00:35

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

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" останется верным.

Улучшенная версия Ответ Берка, которая позволяет использовать 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;
}());

* The properties are read-only, only if the initial values are immutable.

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

angularApp.constant('YOUR_CONSTANT', 'value');

... и вы можете использовать const в VBA ... xbrowser? ... ups ...;)

Quicker 11.03.2016 00:30

OP спрашивает о javascript, ответ касается конкретной сильно самоуверенной структуры JS. Практически не по теме.

rounce 10.05.2016 15:43

@rounce: Ответы не по теме остаются ответами, не флаг их как Не ответ, а проголосовать против и проголосовать за удаление. См. Как правильно использовать флажок «Не отвечает»?

Casimir Crystal 10.05.2016 17:08

@KevinGuan Отметил, сделаю в будущем.

rounce 10.05.2016 20:18

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

создать Enum:

var ConstJs = require('constjs');

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

var myColor = Colors.blue;

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

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

console.info(myColor._id); // output blue 
console.info(myColor.name()); // output blue 
console.info(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.info(curMode.isLogIn()); // output true 
console.info(curMode.isSignUp()); // output false 
console.info(curMode.isForgotPassword()); // output false 

Создать String const:

var ConstJs = require('constjs');

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

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

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

var ConstJs = require('constjs');

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

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

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

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

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

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

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

const name1 = value;

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

По ссылке в ответе это экспериментальная функция, и ее следует использовать с осторожностью.

Johnie Karr 13.06.2015 05:02

Конечно, я с тобой согласен. Но в последних версиях браузеров работает.

Erik Lucio 15.06.2015 10:22

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

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

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

Назначение:

var wildType = CONST_WILD_TYPES.REGULAR;

Сравнение:

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.

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

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

Variables declared via const cannot be re-declared or re-assigned.

В остальном const ведет себя аналогично let.

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

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

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

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

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

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

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

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

Только с IE11 :-(

Mo. 15.06.2017 11:39

Declare a readonly named constatnt.

Variables declared via const cannot be re-declared or re-assigned.

Constants can be declared with uppercase or lowercase, but a common convention is to use all-uppercase letters.

// const c;
// c = 9;   //intialization and declearation at same place
const c = 9;
// const c = 9;// re-declare and initialization is not possible
console.info(c);//9

Другие вопросы по теме