Есть ли способ использовать константы в JavaScript?
Если нет, какова обычная практика указания переменных, которые используются как константы?
try{const thing=1091;}catch(e){var thing=1091;} работает.
Дерек: не будет ли ваш try / catch ограничивать объем того, что вы объявляете блоком try / catch? Если вы неправильно оцениваете объем, то какой смысл вообще указывать const или var?
@Coderer в текущих реализациях, это будет работать, поскольку const имеет ту же область действия, что и var, и это на уровне функций, а не на уровне блоков. Если вместо этого вы будете следовать будущему стандарту ECMAScript, const будет иметь ту же область применения, что и let, а это значит, что он не будет работать.
@Coderer Неправильный язык. Переменные в javascript - это область действия функции. Это не C.
@ Джаспер Это прискорбно. Я сомневаюсь, что они действительно нарушают весь существующий код, использующий const.
@ doug65536 Это не должно нарушать весь код, использующий const. Я думаю, что по крайней мере 90% всего текущего кода все еще будет работать. Код, который может нарушить это изменение, - это код, который должен показаться сомнительным для любого, кто программировал на других языках и знает, что означает слово «область действия». К сожалению, это также означает отсутствие трюков с try, но я, честно говоря, не вижу в этом проблемы, так как странно, что синтаксическая ошибка все равно может быть обнаружена.
Хотя, если честно. Почему у нас нет const var и const let ...
const является частью стандарта Ecma 6, но очевидно, что по крайней мере один браузер реализовал его поддержку до того, как появилась спецификация для Ecma 6; см. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
"стандарты" lol, больше похоже на скользящее окно принятия желаемого за действительное, застрявшее в постоянном состоянии, иногда работающем.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Нет, не в общем. Firefox реализует const, но я знаю, что IE этого не делает.
@Джон указывает на обычную практику именования констант, которая использовалась годами в других языках, я не вижу причин, по которым вы не могли бы это использовать. Конечно, это не значит, что кто-то в любом случае не будет перезаписывать значение переменной. :)
Как всем известно, если IE не реализует его, он может и не существовать.
К сожалению, практически - это правда. IE действительно владеет огромной долей рынка. Если бы у меня был бизнес и внутренние веб-приложения использовались, я бы стандартизировал FF. Я не знаю, почему так много людей заботятся об IE, это просто ужасно.
@Rich: Кто сказал, что мое мнение было правдой? Вы сделали правильное предположение. Кроме того, насколько мне известно, то, что IE - отстой, - это факт. У вас могут быть свои собственные факты, я не говорил, что вы должны верить моим. : P Возьми ксанакс или что-то в этом роде ...
@Rich B, да, это был просто глупый комментарий, и поверьте мне, я бы знал, я делаю много глупых комментариев. @Jason B. - интересно, вчера вечером я столкнулся с этой самой проблемой .. const работает в FF, но не в IE. Спасибо за разъяснение
Кого волнует IE? Я не! FF, Chrome или Opera и т. д. Могут быть установлены почти на любой платформе ОС. Кроме того, продавцы компьютеров обычно знают, что старая версия IE - отстой, поэтому они часто (или даже каждый раз) устанавливают альтернативные браузеры перед продажей компьютера. Поэтому я решил, что в моем разработанном приложении совершенно не будет заботы о несовместимых браузерах: если разработчики браузеров заботятся о соблюдении стандартов, их продукт может использовать мое приложение, если нет, пользователи будут использовать другой браузер ... Я могу жить с этим; -) Но может ли Microsoft жить, теряя часть рынка? Нет, они не могут, поэтому «Они» изменят свою политику разработчиков!
Начиная с 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.
В наши дни (3,5 года спустя) вы можете использовать Object.defineProperty для создания свойств только для чтения, которые также нельзя удалить. Это работает в текущей версии всех основных браузеров (кроме неправильно в IE8). См. Ответ @NotAName
@ Dr.Zim: согласно стандартам кодирования вы никогда не должны использовать ключевое слово const, так как оно не поддерживается в Internet Explorer. Ссылка: google-styleguide.googlecode.com/svn/trunk/…
Итак, что теперь - разрешено использование const или нет?
@Amyth Это бесполезно. Это стиль гид, предложенный единственным поставщиком. В соответствии с указанием Хаски выше, совместимость с IE совершенно не важна при написании серверного JS.
@dngfng 6 лет спустя const поддерживается всеми браузерами, кроме IE10 и более ранних.
Поскольку этот ответ по-прежнему высоко ценится Google в 2015 году, следует сказать, что теперь он устарел. Ключевое слово const теперь официально является частью языка и поддерживается всеми браузерами. По данным statcounter.com, лишь несколько процентов интернет-пользователей все еще используют старые версии браузеров, не поддерживающие const.
const был представлен в другой ответ за шесть лет до этого, который изначально назывался вы можете использовать такие соглашения, как ALL_CAPS.
Это ответ наивный как constпредотвращает только от переназначения! Вы можете сделать что-то вроде: const x = {a: 1};, а затем x.a = 2; Осторожно! Для постоянного постоянного использования: const x = Object.freeze({a: 1});
Почему вы сравниваете IE с браузерами? они не одного типа
@ Black-Hole IE == otherBrowser, даже если IE! == otherBrowser
Я использую const вместо var в своих скриптах Greasemonkey, но это потому, что они будут работать только в Firefox ...
Соглашение об именах действительно может быть подходящим вариантом (я делаю и то, и другое!).
Какое-то время я указывал «константы» (которые на самом деле не были константами) в объектных литералах, передаваемых операторам with(). Я думал, что это было так умно. Вот пример:
with ({
MY_CONST : 'some really important value'
}) {
alert(MY_CONST);
}
Раньше я также создавал пространство имен CONST, в которое помещал все свои константы. Опять же, с накладными расходами. Блин.
Теперь я просто делаю var MY_CONST = 'whatever'; для ЦЕЛОВАТЬ.
Если есть что-то более злое, чем злое, то это определенно with.
eval очень злой! Однажды она сожгла мой дом!
Вы пытаетесь защитить переменные от изменений? Если да, то вы можете использовать шаблон модуля:
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 ().
Красивое решение. Но такие вещи следует оформить в виде библиотеки, чтобы не изобретать их заново в каком-либо новом проекте.
CONFIG.get = someNewFunctionThatBreaksTheCode ... В общем, вы абсолютно не можете применять константы в JS (без ключевого слова const). Единственное, что вы можете сделать, это ограничить видимость.
Я верю, что private - это будущее зарезервированное слово в JavaScript, я бы не стал его использовать на вашем месте.
Это тоже шаблон реестра.
@MathewByrne И еще одно преимущество этого; вы не можете сломать его, назначив другую функцию вместо get, как сказал Томас Эдинг ...;) (Если, конечно, вы не назначаете функцию через config). Это красивое и удобочитаемое решение, которое будет работать в большинстве случаев.
Спасибо за обращение к контексту проблемы. Вы также показали нам, как использовать частные переменные и получать к ним доступ извне.
Этот Только защищает от модификации для примитивные типы данных. Если 'MY_CONST': [1,2,3], вы все равно можете сделать CONFIG.get('MY_CONST').push(4).
Это также упускает одно преимущество констант - если есть опечатка, код не сломается. Таким образом, CONFIG.get('MY_CONTS') вернет undefined, а не ошибку, что затруднит выявление опечатки.
Ключевое слово const находится в черновик ECMAScript 6, но пока поддерживает лишь небольшую часть браузера: http://kangax.github.io/compat-table/es6/. Синтаксис:
const CONSTANT_NAME = 0;
Если вы попытаетесь присвоить значение const, он не выдаст никаких ошибок. Присваивание просто не выполняется, и константа все еще имеет свое исходное значение. Это серьезный недостаток дизайна. ИМХО, но пока существует четкое, последовательное соглашение об именах (например, популярное ALL_CAPS), я не думаю, что это вызовет слишком много проблем.
Следите за поддержкой браузера здесь: kangax.github.io/es5-compat-table/es6/#const
Назначение @MatrixFrog вызовет ошибку с 'use strict'.
Следует ли определять константы в ALL CAPS?
@Tresdin Это общепринятое соглашение об именах, определяющее константы заглавными буквами. Ничто в спецификации языка не заставляет это делать, но это неплохая идея. Это проясняет ваши намерения и улучшает читаемость кода.
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 за нестандартное мышление.
VBScript? Это что? ;)
Обычно я голосую за общий вопрос, связанный с кроссбраузерностью, с конкретным ответом IE. Потому что я ненавижу людей, которые думают, что реализация javascript IE - «Единственная», а другие просто игнорируются. Кто, кстати, использует другие браузеры, кроме IE?
@Cooluhuru этот скрипт, похоже, обрабатывает как браузеры IE (с использованием VBScript), так и браузеры, отличные от IE (с использованием JavaScript const). Вы можете объяснить, что с этим не так?
Мне все еще трудно принять, что константы можно изменять.
В JavaScript я предпочитаю использовать функции для возврата постоянных значений.
function MY_CONSTANT() {
return "some-value";
}
alert(MY_CONSTANT());
Стоит отметить, что это относится к той же проблеме, что и в ответе @Burkes (комментарий @trinithis). `MY_CONSTANT = function () {вернуть" какое-то другое значение "; } ломает это. +1 впрочем, достойное и быстрое решение.
-1. Это не имеет преимуществ по сравнению с var SOME_NAME = value (оно все еще изменяемо), это больше кода и требует объяснения.
@PatrickM, хотя это правда, что вы можете изменять такие псевдоконстанты на других языках, например, C, на котором вы изменяете константы не должен быть в состоянии, вы все равно можете сделать это, например, указатели. Итак, пока вы используете какой-то подход, который, по крайней мере, предлагает, что это константа, это нормально, imo.
ECMAScript 5 вводит Object.defineProperty:
Object.defineProperty (window,'CONSTANT',{ value : 5, writable: false });
Это поддерживается в каждом современном браузере (как и IE ≥ 9).
См. Также: Object.defineProperty в ES5?
Стоит отметить, что это не похоже на традиционную константу. Это позволит вам определить только постоянное свойство (непостоянного объекта). Также это не вызывает ошибки и даже возвращает значение, которое вы пытаетесь установить. Он просто не записывает значение.
Недавно я прочитал, что попытка присвоения свойству с помощью writable: falseволя фактически вызывает ошибку, если код, выполняющий присвоение, интерпретируется в строгом режиме ECMAScript 5. Еще одна причина написать 'use strict' в вашем коде.
Фактически вы можете опустить writable: false, поскольку это дефолт.
В 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 не определен.
Вы можете легко оснастить свой скрипт механизмом для констант, которые можно устанавливать, но нельзя изменять. Попытка их изменить приведет к ошибке.
/* 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, andWeakMap, as well as__proto__for improved interoperability.
«он никогда не был доступен во всех браузерах». Если вы не сделаете его доступным в IE, он никогда не будет доступен во всех браузерах.
стандартизация вождения не для всех;) - компании приходят и уходят снова - спасибо, что указали разногласия в лесу
еще один по этому поводу: VBA еще не является консенсусной функцией во всех браузерах, а MS поддерживает const в VBA - это мастерство распределения бюджетов на разработку;)
Хорошо, это уродливо, но дает мне константу в 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.
Люблю этот код! Как ни крути, но хороший тест на поддержку констант. знак равно
несколько забавно, эй - сколько строк можно ввести, чтобы объявить константу?
Забудьте об IE и используйте ключевое слово const.
работает для меня! но потом я пишу расширение для Chrome, так что я знаю, что использую нормальный браузер ...
@yoyo лучшая часть написания расширений и надстроек - кроссбраузерной поддержки нет!
@Ian Добро пожаловать в 2019 год, кроссбраузерность практически исчезла :)
Введение констант в 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.
Это хорошее решение, которое можно было бы красиво оформить в виде библиотеки для включения. Но мне не нравится именование ваших переменных в этом коде. Зачем отбрасывать описательные имена, такие как «имя» и «значение», используемые в коде Кита? Мелкая проблема, но все же.
Мое мнение (работает только с предметами).
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 - с другим значением - он изменит значение.
Не «не работает в сафари», не поддержанный в сафари. Не то же самое. И он должен выдать 'Uncaught TypeError: Cannot redefine property: <property name here>', если вы попробуете это. либо вы делаете это неправильно, либо ваш ff неправильно его реализовал. Думаю, это сочетание того и другого.
Rhino.js реализует const в дополнение к тому, что было упомянуто выше.
Ясно, что это показывает необходимость стандартизированного ключевого слова const для кросс-браузеров.
Но сейчас:
var myconst = value;
или же
Object['myconst'] = value;
И то и другое кажется достаточным, а все остальное похоже на стрельбу по мухе из базуки.
возьмите старый добрый var myconst = value; а для отладки используйте дополнительный код отладки ... - работает как сумасшедший, если не все браузеры поддерживают const
Тем не менее, нет точного предопределенного способа для кросс-браузера, вы можете добиться этого, контролируя объем переменных, как показано в других ответах.
Но я предлагаю использовать пространство имен, чтобы отличаться от других переменных. это снизит вероятность столкновения с другими переменными до минимума.
Правильное пространство имен, например
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 реализует постоянную функцию, идентичную этому коду.
Просто, лаконично и отвечает духу вопроса ОП. Это должно было получить больше голосов.
У меня это никогда не работало. Несмотря на то, что закрытие делает его неизменным, переменную, которую вы ему назначаете, все равно можно перезаписать. Пример: a = constant(10); a(10); // 10, за которым следует a = constant(25); a(); //25, ошибок или предупреждений нет, нет никаких указаний на то, что ваша константа была нарушена.
Если я переназначу значение a, оно изменится на новое значение
"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.
Я бы, если бы не сломанная реализация i
Примечание: это ведет себя аналогично объявлению ES6 const, например. свойства нельзя повторно объявить или переназначить, но если они имеют тип данных object, они могут быть изменены.
Именно то, что я искал. Вы также можете использовать const constants вместо var constants, чтобы предотвратить переназначение переменной.
См., Например, морозильная камера для рекурсивного замораживания.
Использование комбинации const и Object.freeze() в основном эквивалентно константе из других языков программирования.
Другая альтернатива - это что-то вроде:
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 ...;)
OP спрашивает о javascript, ответ касается конкретной сильно самоуверенной структуры JS. Практически не по теме.
@rounce: Ответы не по теме остаются ответами, не флаг их как Не ответ, а проголосовать против и проголосовать за удаление. См. Как правильно использовать флажок «Не отвечает»?
@KevinGuan Отметил, сделаю в будущем.
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;
Это не может измениться путем переназначения.
По ссылке в ответе это экспериментальная функция, и ее следует использовать с осторожностью.
Конечно, я с тобой согласен. Но в последних версиях браузеров работает.
По возможности группируйте константы в структуры:
Пример в моем текущем игровом проекте я использовал ниже:
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
constcannot 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 :-(
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
Chromeпозволяет использовать ключевое словоconstдля использования констант. напримерconst ASDF = "asdf". Однако, посколькуconstне поддерживает несколько браузеров, я обычно придерживаюсь декларацииvar.