JavaScriptに定数はありますか?


1132

JavaScriptで定数を使用する方法はありますか?

そうでない場合、定数として使用される変数を指定するための一般的な方法は何ですか?


35
Chromeキーワードconstを使用して定数を使用できます。例えばconst ASDF = "asdf"。ただし、constはマルチブラウザに対応していないため、通常はvar宣言を使用します。
Jacksonkr

20
try{const thing=1091;}catch(e){var thing=1091;}動作します。
Derek━會功夫

13
Derek:try / catchは、宣言するもののスコープをtry / catchブロックに制限しませんか?あなたが適切にスコープしていない場合は、指定のポイント何constvarまったくか?
Coderer 2013年

8
現在の実装では@Coderer、これは機能します。constスコープはと同じでvar、ブロックレベルではなく関数レベルです。代わりに次のECMAScript標準に従う場合、はとconst同じスコープを持つため、機能しletません。
Jasper

3
@Coderer間違った言語。JavaScriptの変数は関数スコープです。これはC.ではありません
doug65536

回答:


1018

ES2015以降、JavaScriptには次の概念がありconstます。

const MY_CONSTANT = "some-value";

これは、IE 8、9、10を除くほとんどすべてのブラウザーで機能します厳密モードを有効にする必要がある場合もあります

varALL_CAPSなどの規則を使用して、古いブラウザをサポートする必要がある場合や、レガシーコードを使用している場合に、特定の値を変更してはならないことを示すことができます。

var MY_CONSTANT = "some-value";

60
const x = 24はどうでしょうか。
ザカリースコット

93
ブラウザー間の互換性が必要ない場合(またはRhinoまたはNode.jsでサーバー側のプログラミングをしている場合)、constキーワードを使用できることに注意してください。現在、IEを除くすべての最新ブラウザーでサポートされています。
ハスキー

17
最近(3.5年後)Object.definePropertyに、削除できない読み取り専用プロパティを作成できます。これは、すべての主要ブラウザの現在のバージョンで動作します(ただしIE8では正しく動作しません)。@NotANameの回答を見る
Phrogz

12
@Amythそれは本当に役に立ちません。唯一のベンダーが提案したスタイルガイドです。上記のハスキーのポイントによると、IEの互換性はサーバー側のJSを作成する場合にはまったく無関係です。
2013年

32
この回答は2015年にGoogleによって依然として高いランク付けされているため、現在は古くなっていると言えます。constキーワードは現在、言語の正式一部であり、すべてのブラウザでサポートされています。statcounter.comによると、まだサポートしていない古いブラウザバージョンを使用しているインターネットユーザーは数パーセントにすぎませんconst
トリスタン

310

変数を変更から保護しようとしていますか?もしそうなら、あなたはモジュールパターンを使うことができます:

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

このアプローチを使用すると、値を変更できません。ただし、CONFIG :(でget()メソッドを使用する必要があります。

変数値を厳密に保護する必要がない場合は、提案されているとおりに行い、すべて大文字の規則を使用します。


13
CONFIGの値に対して関数を返すだけでよいことに注意してください。これにより、CONFIG.get()を常に呼び出す必要がなくなります。
Mathew Byrne

4
かなりの解決策。ただし、そのようなものは、新しいプロジェクトで再発明しないようにライブラリとしてラップする必要があります。
andrii 2009年

82
CONFIG.get = someNewFunctionThatBreaksTheCode...全体として、JSで定数を強制することは絶対にできません(constキーワードなし)。できることは、可視性を制限することだけです。
Thomas Eding、2010年

28
私はそれprivateがJavaScriptの将来の予約語であると確信しています。私があなただったら、それを使用しません。
Zaq、2012

これはレジストリパターンでもあります。

122

constキーワードはであるECMAScriptの6案が、それはこれまでのところ唯一のブラウザのサポートの片言楽しん:http://kangax.github.io/compat-table/es6/を。構文は次のとおりです。

const CONSTANT_NAME = 0;

13
に値を割り当てようとしてconstも、エラーはスローされません。割り当ては失敗し、定数は元の値のままです。これは重要な設計上の欠陥です私見ですが、明確で一貫性のある命名規則(人気のあるALL_CAPSなど)がある限り、あまり悲しみの原因になるとは思いません。
MatrixFrog 2010年

6
こちらのブラウザサポートにご注意
Mark McDonald

6
@MatrixFrog割り当ては、でエラーを発生させ'use strict'ます。
sam

で定数を定義する必要がありますALL CAPSか?
ルイス

1
@Tresdinすべての大文字で定数を定義することは一般的な命名規則です。言語仕様にはそれを強制するものはありませんが、それは悪い考えではありません。意図が明確になるため、コードが読みやすくなります。
トカゲに請求

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

Object.freezeを参照してください。参照を読み取り専用にするconst場合にも使用できますconstants


2
これはIE9 + kangax.github.io/compat-table/es5でのみ機能することを言及する必要があり ます。
Cordle

壊れた実装がなければ、私はそうしますi
Alnitak

注:これはES6 const宣言と同様に動作します。たとえば、プロパティを再宣言したり、再割り当てしたりすることはできませんが、datatypeの場合、プロパティobjectを変更できます。
le_m

まさに私が探していたもの。のconst constants代わりにvar constantsを使用して、変数が再割り当てされるのを防ぐこともできます。
Jarett Millard

たとえば、再帰的なフリーズについては、deep-freezeを参照してください。
2017

64

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>

50
男の子、クロスブラウザーではない何かについて話します。。。まだ箱の外で少し考えるための+1。
トム

14
VBScript?あれは何でしょう?;)
tybro0103 2013

2
私は通常、IE固有の回答とともに、一般的な関連するクロスブラウザーの質問に投票します。IEのJavaScriptの実装は「1つ」であり、他は無視されるだけだと考える人が嫌いです。だれがIE以外のブラウザを使用していますか?
2013年

@Cooluhuruこのスクリプトは、IEブラウザー(VBScriptを使用)と非IEブラウザー(JavaScriptを使用const)の両方を処理するようです。それの何が悪いのか説明できますか?
Andrew Grimm

定数を変更できることを受け入れるのにまだ苦労しています。
Norbert Norbertson、2018年

59

ECMAScript 5は以下を導入していObject.definePropertyます:

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

それはだ、すべての近代的なブラウザでサポートされている(だけでなく、IE≥9)。

参照:ES5のObject.defineProperty?


1
これは従来の定数とは異なります。これにより、(非定数オブジェクトの)定数プロパティのみを定義できます。また、これはエラーを生成せず、設定しようとした値を返します。それは単に値を書きません。
Cory Gross

3
私は最近でプロパティに割り当てるしようとすることを読みwritable: false ます割り当てを行うコードはECMAScriptの5のstrictモードの下で解釈されている場合、実際にエラーがスローされます。'use strict'コードに書き込む理由の1つにすぎません。
コリーグロス

6
これwritable: falseデフォルトなので、実際には省略できます
2014年

24

いいえ、一般的ではありません。Firefoxは実装してconstいますが、IEは実装していません。


@Johnは、長年他の言語で使用されてきたconstの一般的な命名規則を指していますが、これを使用できなかった理由はわかりません。もちろん、それは誰かがとにかく変数の値を上書きしないという意味ではありません。:)


11
誰もが知っているように、IEがそれを実装しなければ、存在しない可能性もあります。
ジョシュヒンマン

3
残念ながら、そして実際に言えば-それは本当です。IEは市場で大きなシェアを持っています。私がビジネスを所有していて、内部でWebアプリケーションを使用している場合、FFを標準化します。なぜ多くの人がIEを気にするのか、私にはわかりません。
Jason Bunting

@リッチ:私の意見は事実だと誰が言ったのですか?あなたはかなりの仮定をしました。その上、私に関する限り、IEが吸うという事実は事実です。あなたはあなた自身の事実を持つことができます、あなたが私のものを信じなければならなかったと私は言いませんでした。:Pザナックスか何かを取ります...
ジェイソン・バンティング

@Rich B、ええ、それは単なる馬鹿げたコメントでした、そして私を信じてください、私は知っています、私はたくさんの馬鹿なコメントをします。@Jason B.-興味深いことに、私は昨夜この非常に問題に遭遇しました.. constはFFで動作しましたがIEでは動作しませんでした。説明してくれてありがとう

誰がIEを気にしますか?私はしません!FF、Chrome、Operaなどは、ほぼすべてのOSプラットフォームにインストールできます。また、コンピューターの小売業者は通常、古いIEのバージョンが悪いことを知っているので、コンピューターを販売する前に、代替ブラウザーを頻繁に(または毎回)インストールします。開発したアプリが互換性のないブラウザーについてまったく気にしないことを決めました。ブラウザー開発者が自社のアプリが私のアプリを使用できる標準を尊重することに関心がある場合、そうでない場合、ユーザーは別のブラウザーを使用します... -)しかし、Microsoftは市場の一部を失う可能性がありますか?いいえ、彼らはできないので、「彼ら」は彼らの開発政治を変えるでしょう!
ウィリーウォンカ2017年

20

JavaScriptでは、定数を返す関数を使用するのが私の好みです。

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


alert(MY_CONSTANT());

6
これは、@ Burkesの回答(@trinithis 'コメント)で言及されているのと同じ問題に該当することを指摘する価値があります。`MY_CONSTANT = function(){return" some-other-value "; }はそれを壊します。+1でも、まともで迅速な解決策。
Patrick M

13
-1。これはvar SOME_NAME = value(まだ変更可能です)よりもメリットがなく、より多くのコードであり、説明が必要です。
mikemaccana 2013年

@PatrickMそのような疑似定数を変更できることは事実ですが、たとえばCのような他の言語では、定数変更できないはずですが、ポインタなどを使用してそれを行うことができます。したがって、少なくとも定数であると示唆するアプローチを使用している限り、それは問題ありません。
2014

20

Mozillas MDN Webドキュメントには、に関する良い例と説明が含まれていますconst。抜粋:

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

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

しかし、IE9 / 10がまだサポートしていないのは残念ですconst。そしてそれがばかげている理由:

では、IE9はconstで何をしているのでしょうか?これまでのところ、私たちの決定はそれをサポートしないことです。すべてのブラウザで利用できるようになったことがないため、まだコンセンサス機能ではありません。

...

結局のところ、Webのための最良の長期的な解決策は、それを省いて標準化プロセスが進むのを待つことです。

他のブラウザが正しく実装していないため、実装していませんか?!それをより良くすることを恐れすぎますか?標準の定義の有無にかかわらず、定数は定数です。一度設定すると、変更されることはありません。

そしてすべてのアイデアに:すべての関数(XSSなど)を上書きできます。したがって、varまたはに違いはありませんfunction(){return}const唯一の実定数です。

更新:IE11 以下をサポートしますconst

IE11はLETを含む新興のECMAScript 6標準の明確に定義され、一般に使用される機能のサポート含むconstMapSet、およびWeakMap、ならびに__proto__ための改良された相互運用性を。


25
「それはすべてのブラウザで利用可能ではありませんでした」。IEで使用できるようにしないと、すべてのブラウザーで使用できません。
km1 2012

企業が来て、彼らは再び行く- - )木材にオッズを引用してくれてありがとう、標準化を駆動することは皆のためではありません
より迅速な

これについてもう1つ:VBAはまだすべてのブラウザーでコンサス機能ではなく、MSはVBAでconstをサポートしています-これは開発予算のチャネリングの習得です;)
速い

17

関数を使用してもかまわない場合:

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

このアプローチは、あなたの代わりに、通常の変数の関数与えますが、それは保証*誰もそれのセットに一度値を変えることはできませんことを。

a = constant(10);

a(); // 10

b = constant(20);

b(); // 20

私は個人的に、特にノックアウトのオブザーバブルからこのパターンに慣れた後、これをかなり楽しいと感じています。

*関数を呼び出すconstant前に誰かが関数を再定義しない限り


1
underscore.jsは、このコードと同じ定数関数を実装します。
2014年

シンプルで簡潔、OPの質問の精神に答えます。これはより多くの賛成投票を受け取るべきでした。
Mac

3
これは本当に私にとってはうまくいきませんでした。クロージャはそれを不変にしますが、それに割り当てた変数は引き続き上書きできます。例:にa = constant(10); a(10); // 10続いてa = constant(25); a(); //25、エラーや警告が表示されず、定数が壊れていることを示しません。
Patrick M

に値を再割り当てするとa、それは新しい値に変更されます
Saurabh Sharma

17

「新しい」オブジェクトAPIを使用すると、次のようなことができます。

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

詳細については、Mozilla MDN でこれを参照してください。オブジェクトにアタッチされているため、これは第1レベルの変数ではありませんが、スコープがあれば、それにアタッチできます。this同様に動作するはずです。したがって、たとえばグローバルスコープでこれを行うと、ウィンドウ上で疑似定数値が宣言されます(これは本当に悪い考えです。グローバル変数を不注意に宣言しないでください)。

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

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

注:割り当てはコンソールで割り当てられた値を返しますが、変数の値は変更されません


サファリ、およびモジラでは、別の値を使用してdefineステートメントを再度実行すると、値が再割り当てされます。
Akshay、

2
「サファリでは機能しません」、サファリではサポートされていません。同じではありません。そして、それを試みた場合、「Uncaught TypeError:Cannot redefine property:<property name here>」をスローするはずです。あなたがそれを間違っているか、あなたのffがそれを正しく実装していません。両方の組み合わせだと思います。
tenshou 2013

14

可能な場合は、定数を構造体にグループ化します。

たとえば、現在のゲームプロジェクトでは、以下を使用しました。

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は、「const」宣言を持つ新しいES6標準に対応しています。
上記は、IE8、IE9、IE10などの以前のブラウザーで動作します。


12

設定はできるが変更はできない定数のメカニズムをスクリプトに簡単に装備できます。それらを変更しようとすると、エラーが生成されます。

/* 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を忘れて、constキーワードを使用します。


9
私のために働く!しかし、Chrome拡張機能を作成しているので、正常なブラウザを使用していることがわかります...
yoyo

1
@yoyoの拡張機能とアドオンの作成についての最良の部分-クロスブラウザーのサポートなし!
Ian

1
@Ian 2019へようこそ。クロスブラウザの不整合はほとんどなくなりました:)
Fusseldieb

9

それでも、正確なクロスブラウザーの事前定義された方法はありません。他の回答に示されているように、変数のスコープを制御することで実現できます。

しかし、名前空間を使用して他の変数と区別することをお勧めします。これにより、他の変数による衝突の可能性が最小限に抑えられます。

のような適切なネームスペース

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

それを使用している間iw_constant.nameまたはiw_constant.age

Object.freezeメソッドを使用して、新しいキーの追加やiw_constant内のキーの変更をブロックすることもできます。ただし、レガシーブラウザではサポートされていません。

例:

Object.freeze(iw_constant);

古いブラウザでは、凍結メソッドにポリフィルを使用できます。


関数の呼び出しに問題がない場合は、ブラウザ間で定数を定義する方法が最適です。自己実行関数内でオブジェクトをスコープし、定数の取得関数を返すex:

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

       };

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

//値を取得するには iw_constant('name')iw_constant('age')


**どちらの例でも、オブジェクトまたは関数が他のライブラリを通じて置き換えられないように、名前の間隔に非常に注意する必要があります(オブジェクトまたは関数自体が置き換えられる場合は、定数全体が移動します)。


7

しばらくの間、with()ステートメントに渡されるオブジェクトリテラルに "定数"(実際には定数ではなかった)を指定しました。とても賢いと思った。次に例を示します。

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

過去には、CONSTすべての定数を置く名前空間も作成しました。繰り返しますが、オーバーヘッドがあります。シーッシュ。

今、私はただKISSにvar MY_CONST = 'whatever';行きます。


16
evalより悪質なものがある場合、それは間違いありませんwith
NikiC、2011年

4
evalは非常に悪です!それは私の家を一度焼失した!
W3Geek

6

私の意見(オブジェクトでのみ機能します)。

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

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

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

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

やってみよう!しかし、理解してください-これはオブジェクトですが、単純な変数ではありません。

以下も試してください:

const a = 9;

5

私もこれに問題がありました。そして、かなり長い間、答えを探して、全員のすべての応答を見た後、私はこれに対する実行可能な解決策を思いついたと思います。

私が出くわした答えのほとんどは、定数を保持する関数を使用しているようです。MANYフォーラムのユーザーの多くが投稿しているように、クライアント側のユーザーは関数を簡単に上書きできます。定数オブジェクトには外部からはアクセスできず、内部の関数からしかアクセスできないというキース・エヴェッツの回答に興味をそそられました。

だから私はこの解決策を思いつきました:

すべてを匿名関数の中に入れて、変数、オブジェクトなどをクライアント側で変更できないようにします。また、他の関数が内部から「実際の」関数を呼び出すようにして、「実際の」関数を非表示にします。関数を使用して、クライアント側のユーザーによって関数が変更されたかどうかを確認することも考えました。関数が変更されている場合は、内部で「保護」されていて変更できない変数を使用して元に戻します。

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

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

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

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

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

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

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

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

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

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

また、セキュリティは本当に問題であり、クライアント側からプログラミングを「隠す」方法はないようです。私にとっての良い考えは、プログラマーを含むあなたを含む誰もがそれを読んで理解することが本当に難しいようにコードを圧縮することです。あなたが行くことができるサイトがあります:http : //javascriptcompressor.com/。(これは私のサイトではありません。私が広告を出していないので心配しないでください。)これは、Javascriptコードを無料で圧縮および難読化できるサイトです。

  1. 上記のスクリプトのすべてのコードをコピーして、javascriptcompressor.comページの上部のtextareaに貼り付けます。
  2. Base62エンコードチェックボックスをチェックし、変数を縮小チェックボックスをチェックします。
  3. 圧縮ボタンを押します。
  4. すべてを.jsファイルに貼り付けて保存し、ページの先頭に追加します。

これは、含めるライブラリとしてうまくまとめることができる優れたソリューションです。しかし、このコードでの変数の命名は嫌いです。キースのコードで使用されている「名前」や「値」などの説明的な名前を削除するのはなぜですか?小さな問題ですが、それでも問題はありません。
Cordle

5

明らかに、これは標準化されたクロスブラウザーのconstキーワードの必要性を示しています。

しかし、今のところ:

var myconst = value;

または

Object['myconst'] = value;

どちらも十分に見え、それ以外はバズーカでフライを撃つようなものです。


古き良き変数myconst = valueを取ります。デバッグには、追加のデバッグコードを使用します
...-

4

私は、Greasemonkeyスクリプトconstvarはなくを使用していますが、これは、Firefoxでのみ実行されるためです...
命名規則も確かに有効です(両方を実行します)。


4

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

4

わかりました、これは醜いですが、FirefoxとChromiumでは定数、SafariとOperaでは定数(WTF?)、IEでは変数が得られます。

もちろんeval()は悪ですが、それがなければ、IEはエラーをスローし、スクリプトの実行を妨げます。

SafariとOperaはconstキーワードをサポートしていますが、constの値を変更できます

この例では、サーバー側コードがJavaScriptをページに書き込み、{0}を値に置き換えています。

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

これは何に適していますか?クロスブラウザではないため、それほど多くありません。せいぜい、少なくとも一部のブラウザでは、ブックマークレットやサードパーティのスクリプトが値を変更できないようにして、多少の安心はあります。

Firefox 2、3、3.6、4、Iron 8、Chrome 10、12、Opera 11、Safari 5、IE 6、9でテスト済み。


1
そのコードが大好きです!見た目は醜いが、constサポートのテストとしては良い。=)
Stein G. Strindhaug、2011

1
ややおかしい、ey-constを宣言するために何行入力できますか?
より迅速な

4

それは言及する価値がある場合は、で定数を定義することができ、角度使用します$provide.constant()

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

...そして、VBAでconstを使用できます... xbrowser?... ups ...;)
Quicker

OPはjavascriptについて質問し、特定の非常に意見の高いJSフレームワークを扱います。実質的に話題外。
16年

2
@rounce:オフトピック答えはない、まだ答えているフラグとしてそれらを答えられないが、downvote削除に投票代わりに。「回答なし」フラグを適切に使用する方法を
Kevin Guan

@KevinGuan注目され、将来的に行われます。
2016年

4

代わりに行うことができるバークの答えの改良版CONFIG.MY_CONSTCONFIG.get('MY_CONST')

IE9 +または実際のWebブラウザーが必要です。

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

*初期値が不変である場合のみ、プロパティは読み取り専用です。


4

JavaScript ES6 は、すべての主要なブラウザでサポートされているconstキーワードを(再)導入しました。

を介して宣言された変数はconst、再宣言または再割り当てできません。

それ以外は、とconst同様に動作しletます。

これは、プリミティブデータ型(ブール、ヌル、未定義、数値、文字列、シンボル)に対して期待どおりに動作します。

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

注意:オブジェクトに関する落とし穴に注意してください。

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

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

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

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

不変で完全に一定のオブジェクトが本当に必要な場合:const ALL_CAPS意図を明確にするために使用します。constとにかく、すべての宣言について従うのは良い慣習なので、それだけに頼ってください。


IE11からのみ:-(
Mo.

3

別の選択肢は次のようなものです:

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"真のままであろう。


3

JavaScriptには定数がすでに存在します。次のような定数を定義します。

const name1 = value;

これは、再割り当てによって変更することはできません。


回答のリンクによると、これは実験的な機能であり、注意して使用する必要があります。
ジョニー・カー2015年

もちろん、私はあなたに同意します。しかし、ブラウザの最新バージョンでは動作します。
Erik Lucio

3

キーワード 'const'は以前に提案され、現在ES6に正式に含まれています。constキーワードを使用すると、不変の文字列として機能する値/文字列を渡すことができます。


2

JavaScriptに定数を導入することはせいぜいハックです。

JavaScriptで永続的かつグローバルにアクセス可能な値を作成する良い方法は、次のようないくつかの「読み取り専用」プロパティを持つオブジェクトリテラルを宣言することです。

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

すべての定数が1つの「my」アクセサリオブジェクトにグループ化され、格納された値や、そのためにそこに置くことを決定したその他のものを検索できます。それが機能するかどうかをテストしましょう:

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

ご覧のとおり、「my.constant1」プロパティは元の値を保持しています。あなたはあなた自身にいくつかの素敵な「緑の」一時定数を作りました...

しかしもちろん、これは、指定された例のように、直接アクセスしてプロパティ定数値を誤って変更、変更、無効化、または空にすることから保護するだけです。

それ以外の場合は、定数はダミー用であるとまだ思います。そして、私はあなたの偉大な自由を欺くセキュリティの小さなコーナーと交換することは可能な最悪の取引だと今でも思います。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.