JavaScript'te sabitler var mı?


1132

JavaScript'te sabit kullanmanın bir yolu var mı ?

Değilse, sabit olarak kullanılan değişkenleri belirlemek için yaygın uygulama nedir?


35
Chromeconstsabitleri kullanmak için anahtar kelimeyi kullanmanıza olanak tanır . örn const ASDF = "asdf". Ancak, constçoklu tarayıcı uyumlu olmadığından, genellikle bir varbildirime bağlı kalıyorum .
Jacksonkr

20
try{const thing=1091;}catch(e){var thing=1091;}İşler.
Derek 朕 會 功夫

13
Derek: try / catch'iniz try / catch bloğuna bildirdiğiniz şeyin kapsamını sınırlamaz mı? Eğer kapsam değilseniz düzgün sonra belirterek ne anlamı var constya varhiç?
Coderer

8
@Coderer mevcut uygulamalarda, bu constaynı kapsamda olduğu gibi çalışacaktır varve bu blok düzeyinde değil, fonksiyon seviyesinde. Bunun yerine yaklaşan ECMAScript standardını izlerseniz const, aynı kapsamı kullanır let, bu da çalışmaz demektir.
Jasper

3
@Coderer Yanlış dil. Javascript değişkenleri fonksiyon kapsamıdır. Bu C değil
doug65536

Yanıtlar:


1018

ES2015'ten beri JavaScript'in bir fikri vardır const:

const MY_CONSTANT = "some-value";

Bu, IE 8, 9 ve 10 dışındaki hemen hemen tüm tarayıcılarda çalışır . Bazılarının katı modun etkinleştirilmesi de gerekebilir .

varEski tarayıcıları desteklemeniz gerekiyorsa veya eski kodla çalışıyorsanız, belirli değerlerin değiştirilmemesi gerektiğini göstermek için ALL_CAPS gibi kurallarla kullanabilirsiniz :

var MY_CONSTANT = "some-value";

60
Sabit x = 24;
Zachary Scott

93
Çapraz tarayıcı uyumluluğuna ihtiyacınız yoksa (veya Rhino veya Node.js'de sunucu tarafı programlamanız varsa) constanahtar kelimeyi kullanabileceğinizi unutmayın . Şu anda IE dışındaki tüm modern tarayıcılar tarafından desteklenmektedir.
Husky

17
Bu günlerde (3,5 yıl sonra) Object.definePropertysilinemeyen salt okunur özellikler oluşturmak için de kullanabilirsiniz. Bu, tüm büyük tarayıcıların geçerli sürümünde çalışır (ancak yanlış IE8'de ). @NotAName
Phrogz

12
@Amyth Bu gerçekten yardımcı değil. Tek bir satıcı tarafından önerilen bir stil rehberi . Husky'nin yukarıdaki noktasına göre, sunucu tarafı JS yazarken IE uyumluluğu tamamen önemsizdir.
aendrew

32
Bu cevap 2015 yılında hala Google tarafından yüksek derecede derecelendirildiğinden, artık kullanılmadığı söylenmelidir. constAnahtar kelime artık dilin resmen parçasıdır ve her tarayıcı tarafından desteklenmektedir. Statcounter.com'a göre internet kullanıcılarının sadece yüzde bir kısmı hala desteklemeyen eski tarayıcı sürümlerini kullanıyor const.
tristan

310

Değişkenleri değişikliğe karşı korumaya mı çalışıyorsunuz? Öyleyse, bir modül deseni kullanabilirsiniz:

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

Bu yaklaşım kullanılarak değerler değiştirilemez. Ancak, CONFIG :( üzerinde get () yöntemini kullanmalısınız.

Değişkenlerin değerini kesinlikle korumanız gerekmiyorsa, önerildiği gibi yapın ve ALL CAPS kuralını kullanın.


13
CONFIG değeri için bir işlev döndürebileceğinizi unutmayın. Bu, CONFIG.get () öğesini her zaman çağırmanızı sağlar.
Mathew Byrne

4
Güzel çözüm. Ancak bu tür şeyler, herhangi bir yeni projede yeniden icat edilmemek için bir kütüphane olarak sarılmalıdır.
andrii

82
CONFIG.get = someNewFunctionThatBreaksTheCode... Sonuç olarak, JS'de sabitleri kesinlikle uygulayamazsınız (wt veya const anahtar sözcüğü). Yapabileceğiniz tek şey görünürlüğü sınırlamak.
Thomas Eding

28
privateJavaScript'te gelecekteki ayrılmış bir kelime olduğuna inanıyorum, siz olsaydım bunu kullanmazdım.
Zaq

Bu aynı zamanda kayıt desenidir.

122

constAnahtar kelimenin bulunduğu ECMAScript 6 taslak ama şimdiye kadar sadece tarayıcı desteği çat pat sahiptir: http://kangax.github.io/compat-table/es6/ . Sözdizimi:

const CONSTANT_NAME = 0;

13
A öğesine bir değer atamaya çalışırsanız const, herhangi bir hata atmaz. Atama başarısız olur ve sabit hala orijinal değerine sahiptir. Bu büyük bir tasarım kusuru IMHO ama açık, tutarlı bir adlandırma kuralı olduğu sürece (popüler ALL_CAPS gibi) Çok fazla kedere neden olacağını düşünmüyorum.
MatrixFrog

6
Tarayıcı desteğine bir göz atın
Mark McDonald

6
@MatrixFrog ataması ile bir hata ortaya çıkar 'use strict'.
sam

Sabitleri tanımlamalı mıyım ALL CAPS?
Lewis

1
@Tresdin Tüm büyük harflerde sabitleri tanımlamak yaygın bir adlandırma kuralıdır. Dilde hiçbir şey onu zorlamıyor, ama bu kötü bir fikir değil. Niyetinizin ne olduğunu daha net hale getirir, böylece kod okunabilirliğini artırır.
Kertenkele Bill

68
"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

Bkz. Object.freeze . Referansı salt okunur yapmak istiyorsanız da kullanabilirsinizconstconstants .


2
Bu sadece IE9 + kangax.github.io/compat-table/es5 üzerinde çalışır belirtmek gerekir .
Cordle

Kırık uygulaması olmasaydı yapardımi
Alnitak

Not: Bu, ES6 constbildirimine benzer şekilde çalışır , örn. Özellikler yeniden bildirilemez veya yeniden atanamaz, ancak veri türündeyse bunlar mutasyona uğratılabilir object.
le_m

Tam aradığım şey. Ayrıca kullanabilirsiniz const constantsyerine var constantsyeniden atanmakta olan değişken önlemek için.
Jarett Millard

Örneğin, özyinelemeli dondurma için derin dondurmaya bakın.
sam

64

IE sabitleri destekler, örneğin:

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

50
Evlat, çapraz tarayıcı olmayan bir şey hakkında konuş. . . Hala kutunun dışında düşünmek için +1.
Tom

14
VBScript? Bu da ne? ;)
tybro0103

2
Genellikle IE ile ilgili bir cevap ile ilgili genel çapraz tarayıcılar soru için aşağı Oy. Çünkü IE javascript uygulamasının 'Bir' olduğunu düşünen insanlardan nefret ediyorum ve diğerleri sadece görmezden gelinecek. IE, btw dışında başka borçlular kim kullanıyor?
Karınca

@Cooluhuru bu komut dosyasının hem IE tarayıcılarını (VBScript kullanarak) hem de IE olmayan tarayıcıları (JavaScript kullanarak const) işlediği görülüyor . Neyin yanlış olduğunu açıklayabilir misin?
Andrew Grimm

Sabitlerin değiştirilebileceğini kabul etmekte hala zorlanıyorum.
Norbert Norbertson

59

ECMAScript 5 Object.definePropertyşunları sunar:

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

O var her modern tarayıcıda desteklenen (yanı sıra IE ≥ 9).

Ayrıca bakınız: ES5'te Object.defineProperty?


1
Bunun geleneksel bir sabit gibi olmadığını belirtmek gerekir. Bu yalnızca sabit bir özellik (sabit olmayan bir nesnenin) tanımlamanızı sağlar. Ayrıca bu bir hata oluşturmaz ve hatta ayarlamaya çalıştığınız değeri döndürür. Sadece değeri yazmaz.
Cory Gross

3
Geçenlerde bir özellik atamak denemeden okumak writable: false olacaktır atama yapar kod ECMAScript 5'in katı modda altında yorumlanır olup olmadığını aslında bir hata atmak. 'use strict'Kodunuzu yazmak için başka bir neden .
Cory Gross

6
Aslında writable: falsebu varsayılan olduğu için atlayabilirsiniz .
sam

24

Hayır, genel olarak değil. Firefox uygular constama biliyorum IE değil.


@John , yıllardır diğer dillerde kullanılan sabitler için ortak bir adlandırma uygulamasına işaret ediyor, bunu kullanamamanın bir nedeni göremiyorum. Tabii ki bu, birisinin değişkenin değeri üzerinde zaten yazmayacağı anlamına gelmez. :)


11
Herkesin bildiği gibi IE uygulamıyorsa, mevcut olmayabilir de.
Josh Hinman

3
Ne yazık ki ve pratik olarak - bu doğrudur. IE pazarın büyük bir paya sahiptir. Bir işim varsa ve web uygulamaları şirket içinde kullanılıyor olsaydı, FF'de standartlaşırdım. Pek çok insanın neden IE'yi önemsediğini bilmiyorum, esiyor.
Jason Bunting

@Rich: Fikrimin gerçek olduğunu kim söyledi? Oldukça varsayım yaptınız. Ayrıca, benim endişe duyduğum kadarıyla, IE berbat bir gerçektir. Kendi gerçekleriniz olabilir, benimkine inanmanız gerektiğini söylemedim. : P Bir Xanax ya da başka bir şey al ...
Jason Bunting

@Rich B, evet bu sadece aptalca bir yorumdu ve bana güven, bilirdim, çok aptalca yorumlar yapıyorum. @ Jason B - ilginç, dün gece bu sorunla karşılaştım .. const FF çalıştı ama IE değil. Açıklama için teşekkürler

IE'yi kim önemsiyor? Yapmıyorum! FF veya Chrome veya Opera vb ... neredeyse her işletim sistemi platformuna kurulabilir. Ayrıca bilgisayar perakendecileri genellikle eski IE sürümünü berbat bilirler, böylece bir bilgisayarı satmadan önce genellikle (veya her seferinde) alternatif tarayıcılar yüklerler. Bu yüzden, geliştirilmiş uygulamamın uyumsuz tarayıcılarla hiç ilgilenmemesine karar verdim: tarayıcı geliştiricileri standartlara uymayı önemsiyorsa, ürünleri uygulamamı kullanabilir, değilse, kullanıcılar farklı bir tarayıcı kullanacaktır ... Onunla yaşayabilirim; -) Peki Microsoft pazarın bir kısmını kaybetmekte yaşayabilir mi? Hayır onlar yapamazlar "Onlar" dev politikalarını değiştirecek!
willy wonka

20

JavaScript'te tercihim, sabit değerler döndürmek için işlevleri kullanmaktır.

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


alert(MY_CONSTANT());

6
Bu, @Burkes yanıtında (@trinithis 'yorumu) belirtilen aynı soruna düştüğünü belirtmeye değer. `MY_CONSTANT = function () {return" some-other-value "; } keser. +1 olsa da, iyi ve hızlı bir çözüm.
Patrick M

13
-1. Bunun var SOME_NAME = değerine (hala değişebilir) göre hiçbir faydası yoktur, daha fazla koddur ve açıklanması gerekir.
mikemaccana

Eğer sen hangi örneğin C gibi diğer dilde, sözde sabitler bu tür değiştirebilir doğrudur ederken @PatrickM mümkün olmamalıdır sabitleri değiştirebilir, onları yine de aracılığıyla örneğin işaretçileri yapabilirsiniz. En azından bunun sabit olduğunu gösteren bir yaklaşım kullandığınız sürece , iyi imo.
rev

20

Mozillas MDN Web Dokümanları hakkında iyi örnekler ve açıklamalar içermektedir const. Alıntı:

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

Ancak IE9 / 10'un hala desteklemediği üzücü const. Ve bunun saçma nedeni :

Peki, IE9 const ile ne yapıyor? Şimdiye kadar verdiğimiz karar bunu desteklemedi. Henüz tüm tarayıcılarda bulunmadığı için henüz bir konsensüs özelliği değildir.

...

Sonunda, web için en iyi uzun vadeli çözüm, onu dışarıda bırakmak ve standartlaştırma süreçlerinin ilerlemesini beklemek gibi görünüyor.

Uygulamıyorlar çünkü diğer tarayıcılar doğru şekilde uygulamadı mı ?! Daha iyi yapmaktan korkuyor musun? Standart tanımları ya da değil, sabit bir sabittir: bir kez ayarlanmış, asla değişmemiş.

Ve tüm fikirlere: Her işlevin üzerine yazılabilir (XSS vb.). Yani varveya 'da bir fark yoktur function(){return}. consttek sabittir.

Güncelleme: IE11 destekliyor const :

IE11 let dahil olmak üzere yükselen ECMAScript 6 standart, iyi tanımlanmış ve yaygın olarak kullanılan özellikler için destek içerir const, Map, Setve WeakMapyanı sıra __proto__için gelişmiş çalışabilirlik.


25
"hiçbir zaman tüm tarayıcılarda bulunmadı". IE'de kullanılabilir yapmazsanız, tüm tarayıcılarda asla bulunmayacaktır.
km1

sürüş standardizasyonu herkes için değildir;) - şirketler gelir ve tekrar giderler - ahşaptaki oranları alıntıladığınız için teşekkür ederiz
hızlı

bir tane daha: VBA henüz tüm tarayıcılarda bir vicdan özelliği değil ve MS VBA'da const'u destekliyor - bu, geliştirme bütçelerini kanalize etmenin ustalığı;)
hızlı

17

İşlevleri kullanmanın bir sakıncası yoksa:

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

Bu yaklaşım size normal değişkenler yerine işlevler verir, ancak ayarlandıktan sonra kimsenin değeri değiştiremeyeceğini * garanti eder .

a = constant(10);

a(); // 10

b = constant(20);

b(); // 20

Şahsen bunu oldukça hoş buluyorum, özellikle nakavt gözlemlenebilirlerinden bu desene alıştıktan sonra.

* Birisi işlevi constantçağırmadan önce yeniden tanımlamazsa


1
underscore.js, bu kodla aynı sabit işlevi uygular.
Upperstage

Basit, özlü ve OP sorununun ruhunu cevaplar. Bu daha fazla oy almalıydı.
Mac

3
Bu benim için gerçekten işe yaramadı. Kapatma onu değiştirilemez olsa da, atadığınız varlığın üzerine hala yazılabilir. Örn: a = constant(10); a(10); // 10ardından a = constant(25); a(); //25hata veya uyarı verilmez, sabitinizin bozulduğuna dair bir belirti yoktur.
Patrick M

Değeri yeniden a
Saurabh Sharma

17

"new" Object api ile böyle bir şey yapabilirsiniz:

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

bir göz atın bu fazla özellikleri için Mozilla MDN'yi üzerinde. Bir nesneye bağlı olduğu için birinci düzey bir değişken değildir, ancak bir kapsamınız varsa, herhangi bir şey varsa, bunu ona ekleyebilirsiniz. thisde çalışmalı. Örneğin, bunu küresel kapsamda yapmak, pencerede sahte bir sabit değer bildirecektir (bu gerçekten kötü bir fikirdir, küresel değişkenleri dikkatsizce beyan etmemelisiniz)

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

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

not: atama size konsolda atanan değeri verir, ancak değişkenin değeri değişmez


Safari'de ve mozilla'da tanım deyimini tekrar çalıştırırsanız - farklı bir değerle - değeri yeniden atayacaktır.
Akshay

2
'Safari'de çalışmıyor', Safari'de desteklenmiyor . Aynı değil. Ve bunu denerseniz, 'Yakalanmamış TypeError: özelliği yeniden tanımlanamıyor: <özellik adı>' atmalıdır. ya yanlış yapıyorsunuz ya da ff yanlış uyguladı. Her ikisinin bir karışımı sanırım.
tenshou

14

Sabitleri mümkün olduğunca yapılara gruplayın:

Örnek, şu anki oyun projemde aşağıda kullandım:

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

Görev:

var wildType = CONST_WILD_TYPES.REGULAR;

karşılaştırma:

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

Daha yakın zamanda karşılaştırma için kullanıyorum:

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

IE11, 'const' bildirimi olan yeni ES6 standardına sahiptir.
Yukarıda IE8, IE9 ve IE10 gibi önceki tarayıcılarda çalışır.


12

Komut dosyanızı, ayarlanabilen ancak değiştirilemeyen sabitler için bir mekanizma ile kolayca donatabilirsiniz. Bunları değiştirme girişimi bir hata oluşturur.

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

12

IE'yi unutun ve constanahtar kelimeyi kullanın .


9
benim için çalışıyor! ama sonra bir krom uzantısı yazıyorum, bu yüzden aklı başında bir tarayıcıda olduğumu biliyorum ...
yoyo

1
@yoyo uzantıları ve eklentileri yazma konusunda en iyi bölüm - çapraz tarayıcı desteği yok!
Ian

1
@Ian 2019'a hoş geldiniz, tarayıcılar arası tutarsızlık neredeyse kayboldu :)
Fusseldieb

9

Yine de bunu yapmak için önceden belirlenmiş tam bir çapraz yol yoktur, diğer cevaplarda gösterildiği gibi değişkenlerin kapsamını kontrol ederek bunu başarabilirsiniz.

Ancak diğer değişkenlerden ayırt etmek için ad boşluğu kullanmanızı öneririm. bu, diğer değişkenlerden çarpışma olasılığını en aza indirecektir.

Doğru ad alanı gibi

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

yani kullanırken iw_constant.nameveya olacakiw_constant.age

Ayrıca Object.freeze yöntemini kullanarak yeni bir anahtar eklemeyi veya iw_constant içindeki herhangi bir anahtarı değiştirmeyi engelleyebilirsiniz. Ancak eski tarayıcıda desteklenmez.

örn:

Object.freeze(iw_constant);

Daha eski tarayıcılarda , dondurma yöntemi için çoklu dolgu kullanabilirsiniz .


Arama fonksiyonu ile tamam iseniz aşağıdaki sabit tanımlamak için en iyi çapraz tarayıcı yoludur. Kendi kendini yürütme işlevi içinde nesnenizi kapsamak ve sabitleriniz için bir get işlevi döndürmek örn:

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

       };

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

// değeri kullanmak için iw_constant('name')veyaiw_constant('age')


** Her iki örnekte de, nesne veya işlevinizin başka bir kitaplık aracılığıyla değiştirilmemesi için ad aralığına çok dikkat etmelisiniz. (Nesne veya işlevin kendisi değiştirilecekse tüm sabitiniz gidecektir)


7

Bir süreliğine, with()ifadelere aktarılan nesne değişmezlerinde "sabitler" (aslında sabit olmayanlar) belirledim . Çok zeki olduğunu düşündüm. İşte bir örnek:

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

Geçmişte, CONSTtüm sabitlerimi koyacağım bir isim alanı da yarattım . Yine, tepegöz ile. Sheesh.

Şimdi, ben sadece bunu var MY_CONST = 'whatever';için KISS .


16
Değerlendirmeden daha kötü bir şey varsa, kesinlikle with.
NikiC

4
eval çok kötü! Evimi bir kez yaktı!
W3Geek

6

Bence (sadece nesnelerle çalışır).

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

Deneyin! Ama anlayın - bu nesne, ancak basit bir değişken değil.

Ayrıca şunu da deneyin:

const a = 9;

5

Ben de bu konuda bir sorun yaşadım. Ve bir süre sonra cevabı araştırıp herkesin tüm cevaplarına baktıktan sonra, bunun için uygun bir çözüm bulduğumu düşünüyorum.

Karşılaştığım cevapların çoğu sabitleri tutmak için fonksiyonlar kullanıyor gibi görünüyor. MANY forumlarının birçoğunun yayınladığı gibi, işlevler istemci tarafında kullanıcılar tarafından kolayca yazılabilir. Keith Evetts'in sabiti nesnesine dışarıdan erişilemez, sadece içerideki işlevlerden erişilebileceği yanıtı ilgimi çekti.

Bu çözümü buldum:

Her şeyi anonim bir işlevin içine yerleştirin, böylece değişkenler, nesneler, vb. İstemci tarafı tarafından değiştirilemez. Ayrıca, diğer işlevlerin içeriden 'gerçek' işlevleri çağırmasını sağlayarak 'gerçek' işlevleri gizleyin. Ayrıca, bir işlevin istemci tarafında bir kullanıcı tarafından değiştirilip değiştirilmediğini kontrol etmek için işlevleri kullanmayı düşündüm. İşlevler değiştirilmişse, iç kısımda 'korunan' değişkenleri kullanarak bunları değiştiriniz.

/*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);
  };
}())

Ayrıca güvenlik gerçekten bir sorun gibi görünüyor ve programınızı istemci tarafından 'gizlemenin' bir yolu yok. Benim için iyi bir fikir, kodunuzu sıkıştırmaktır, böylece siz, programcı da dahil olmak üzere herkesin onu okuması ve anlaması zorlaşır. Http://javascriptcompressor.com/ adresine gidebileceğiniz bir site var . (Bu benim sitem değil, endişelenmeyin reklam vermiyorum.) Bu, Javascript kodunu ücretsiz olarak sıkıştırmanıza ve gizlemenize izin veren bir sitedir.

  1. Yukarıdaki koddaki tüm kodu kopyalayın ve javascriptcompressor.com sayfasındaki üst metin alanına yapıştırın.
  2. Base62 kodlaması onay kutusunu işaretleyin, Değişkenleri Daralt onay kutusunu işaretleyin.
  3. Sıkıştır düğmesine basın.
  4. Her şeyi bir .js dosyasına yapıştırın ve kaydedin ve sayfanızın başındaki sayfanıza ekleyin.

Bu, dahil edilecek bir kütüphane olarak güzelce sarılabilecek iyi bir çözümdür. Ama bu koddaki değişkenlerinizin isimlendirilmesinden hoşlanmıyorum. Neden Keith'in kodunda kullanılan "name" ve "value" gibi açıklayıcı isimleri bırakalım? Küçük bir sorun, ama yine de.
Cordle

5

Açıkçası bu, standart bir çapraz tarayıcı const anahtar kelimesine duyulan ihtiyacı gösterir.

Ama şimdilik:

var myconst = value;

veya

Object['myconst'] = value;

Her ikisi de yeterli görünüyor ve başka bir şey bir bazuka ile sinek vurmaya benziyor.


iyi eski var al myconst = değer; ve hata ayıklama için ekstra hata ayıklama kodu kullanın ... - tüm tarayıcılar const desteklemediği sürece deli gibi çalışır
Hızlı

4

Greasemonkey scriptlerimde kullanmak constyerine kullanıyorum var, ancak sadece Firefox'ta çalışacakları için ...
Ad kuralı gerçekten de gidilecek yol olabilir (her ikisini de yaparım!).


4

JavaScript'te benim uygulamam olabildiğince sabitlerden kaçınmak ve bunun yerine dizeleri kullanmak oldu. Sabitlerinizi dış dünyaya göstermek istediğinizde sabitlerle ilgili sorunlar ortaya çıkar:

Örneğin, aşağıdaki Tarih API'sı uygulanabilir:

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

Ancak basitçe yazmak çok daha kısa ve daha doğaldır:

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

Bu şekilde "günler" ve "saatler" sabitler gibi hareket eder, çünkü dışarıdan "saat" in kaç saniye temsil ettiğini değiştiremezsiniz. Ancak üzerine yazmak kolaydır MyModule.Date.HOUR.

Bu tür bir yaklaşım hata ayıklamaya da yardımcı olacaktır. Firebug size action === 18bunun ne anlama geldiğini anlamanın oldukça zor olduğunu söylüyorsa , ancak gördüğünüzde action === "save"hemen anlaşılır.


Ne yazık ki yazım hataları yapmak oldukça kolay - örneğin "Hours"yerine "hours"- ancak bir IDE Date.Hoursbunun tanımlanmadığı konusunda sizi erken bilgilendirebilir .
le_m

4

Tamam, bu çirkin, ama Firefox ve Chromium'da bir sabit, Safari ve Opera'da sabit olmayan bir sabit (WTF?) Ve IE'de bir değişken veriyor.

Elbette eval () kötüdür, ancak onsuz IE bir komut dosyası çalıştırılmasını önleyerek bir hata atar.

Safari ve Opera const anahtar sözcüğünü destekler, ancak const değerini değiştirebilirsiniz .

Bu örnekte, sunucu tarafı kodu sayfaya {0} yerine bir değer yazmaktadır.

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

Bu ne işe yarar? Çok fazla değil, çünkü tarayıcılar arası değil. En azından, bazı tarayıcıların yer imleri veya üçüncü taraf komut dosyalarının değeri değiştirmesine izin vermeyeceği biraz rahat olabilir .

Firefox 2, 3, 3.6, 4, Iron 8, Chrome 10, 12, Opera 11, Safari 5, IE 6, 9 ile test edildi.


1
Bu kodu seviyorum! Çirkin gibi, ama const desteği için iyi bir test. =)
Stein G. Strindhaug

1
biraz komik, ey - bir const bildirmek için kaç satır yazabilirsiniz?
hızlı

4

O söz değer ise, içinde sabitleri tanımlayabilirsiniz açısal kullanarak$provide.constant()

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

... ve VBA'da const kullanabilirsiniz ... xbrowser? ... ups ...;)
hızlı

OP javascript hakkında sorular sorar, özel olarak ağır görüşlü JS çerçevesi ile ilgilenir. Pratik olarak konu dışı.
16'da

2
@rounce: Gündem dışı cevaplar, hala cevap yok olan bayrak onları olarak değil bir cevap ama downvote ve silmek için oy yerine. Bkz . “Yanıt Değil” bayrağını doğru bir şekilde nasıl kullanabilirim?
Kevin Guan

@KevinGuan Noted, gelecekte yapacak.
16'da

4

Burke'ün cevabıCONFIG.MY_CONST yerine yapmanıza izin veren geliştirilmiş bir versiyonu CONFIG.get('MY_CONST').

IE9 + veya gerçek bir web tarayıcısı gerektirir.

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

* Özellikler yalnızca başlangıç ​​değerleri değiştirilemezse salt okunurdur.


4

JavaScript ES6 (yeniden) , tüm büyük tarayıcılarda desteklenen constanahtar kelimeyi tanıttı .

Yoluyla bildirilen değişkenler constyeniden beyan edilemez veya yeniden atanamaz.

Bunun dışında, constbenzer şekilde davranır let.

İlkel veri türleri (Boolean, Null, Unndefined, Number, String, Symbol) için beklendiği gibi davranır:

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

Dikkat: Nesnelerle ilgili tuzaklardan haberdar olun:

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

Gerçekten değişmez ve kesinlikle sabit bir nesneye ihtiyacınız varsa: const ALL_CAPSNiyetinizi netleştirmek için kullanın . constZaten tüm bildirimleri takip etmek iyi bir kongre , bu yüzden sadece ona güven.


Gönderen IE11 sadece :-(
Mo

3

Başka bir alternatif şudur:

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

Sonra basitçe: var foo = constantMap.MY_CONSTANT

Eğer constantMap.MY_CONSTANT = "bar"bir alıcı ile bir atama operatörü kullanmaya çalıştığımız için bunun bir etkisi olmazsa, bu constantMap.MY_CONSTANT === "myconstant"durumda doğru kalır.


3

Javascript'te zaten sabitler var . Aşağıdaki gibi bir sabit tanımlarsınız:

const name1 = value;

Bu, yeniden atama yoluyla değişemez.


Yanıttaki bağlantıya göre, bu deneysel bir özelliktir ve dikkatle kullanılmalıdır.
Johnie Karr

Tabii ki, sana katılıyorum. Ancak tarayıcıların son sürümlerinde çalışır.
Erik Lucio

3

'Const' anahtar kelimesi daha önce önerildi ve şimdi ES6'ya resmen dahil edildi. Const anahtar sözcüğünü kullanarak, değişmez bir dize olarak işlev görecek bir değer / dize iletebilirsiniz.


2

Sabitleri JavaScript ile tanıştırmak en iyi ihtimalle bir hack'tir.

JavaScript'te kalıcı ve global olarak erişilebilir değerler yapmanın güzel bir yolu, aşağıdaki gibi "salt okunur" özelliklerin bulunduğu bir nesne değişmezini bildirmektir:

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

tüm sabitlerinizi tek bir "my" aksesuar nesnesinde gruplandıracaksınız; burada saklanan değerlerinizi veya bu konu için koymaya karar verebileceğiniz başka herhangi bir şeyi arayabilirsiniz. Şimdi çalışıp çalışmadığını test edelim:

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

Gördüğümüz gibi, "my.constant1" özelliği orijinal değerini korudu. Kendinize güzel 'yeşil' geçici sabitler yaptınız ...

Ancak elbette bu, yalnızca, verilen örnekte olduğu gibi, mülk sabit değerinizi doğrudan erişimle yanlışlıkla değiştirmenize, değiştirmenize, geçersiz kılmanıza veya boşaltmanıza engel olacaktır.

Aksi halde sabitlerin aptallar için olduğunu düşünüyorum. Ve hala büyük özgürlüğünüzü aldatıcı güvenliğin küçük bir köşesi ile değiştirmenin mümkün olan en kötü ticaret olduğunu düşünüyorum.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.