質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

4回答

15707閲覧

classのなかでconstを定義したい

torimingo

総合スコア122

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2020/07/20 13:29

classのなかで、constを定義したいです。
簡単そうなのに、ぐぐってもでてきません・・・。

以下のコードだと、console.log(NAME);でエラーが出ます・・・。

<html> <head> </head> <body> <script> class Cat { constructor(name) { const NAME = name; } nya() { console.log(NAME); } } let cat = new Cat("kuro"); cat.nya(); </script> </body> </html>

どうしたらよいでしょう?
ご教授頂けると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hentaiman

2020/07/20 15:44

classという書き方に拘りがなければfunction使えばいいんじゃないかな
torimingo

2020/07/20 23:28

わけがあって、classじゃないと駄目なんです、すみません!
guest

回答4

0

ベストアンサー

Object.definePropertyをうまく使うといいかと。

Object.defineProperty() - JavaScript | MDN

これは、任意のオブジェクトを第一引数にいれ、
第二引数で、プロパティ名を文字列で指定し、
第三引数では、値などのオプションを指定し、プロパティの仕様を定義できます。
デフォルトでは、そのプロパティは再定義・再代入が不可のまさにconstでの定義と同じようにできます。

javascript

1class Cat { 2 constructor(name) { 3 Object.defineProperty( 4 this, 5 'NAME', { 6 value: name 7 } 8 ); 9 } 10 11 nya() { 12 console.log(this.NAME); 13 } 14} 15 16let cat = new Cat("kuro"); 17 18cat.nya();

投稿2020/07/21 00:37

編集2020/07/21 00:42
miyabi_takatsuk

総合スコア9555

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torimingo

2020/07/21 10:45

ご回答ありがとうございました。 definePropertyを拝見して、C言語の#defineを思い出しました。 わかりやすい説明をありがとうございました。
guest

0

classのなかで、constを定義したいです。

classの外側で定義するのが早いです。クラス内でも使えます。

投稿2020/07/20 13:46

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torimingo

2020/07/20 14:32

ご回答ありがとうございます。 外側ですとグローバルなスコープになってしまいませんでしょうか。 class内だけで使えるようなconstを定義するのは難しいでしょうか。
maisumakun

2020/07/20 14:41

> 外側ですとグローバルなスコープになってしまいませんでしょうか。 そうですね、ブラウザで直接書くのでなくWebpackなどを通す場合は、exportしたもの以外はファイルスコープとなります。 (なお、質問文に提示されたコードでは、NAMEはコンストラクタにローカルとなります)
guest

0

classのなかでconstを定義

Object.defineProperties() を活用する代替案です。

JavaScriptのオブジェクトに定義される定数 は以下の特徴があると認識しています。

  • どのインスタンスにも共通の値を持つ
  • スタティックにもアクセスできる
  • インスタンスからもアクセスできる

javascript

1const myConstants = { 2 CONST_VALUE_1: { value:1 }, 3 CONST_VALUE_2: { value:2 } 4} 5 6class MyClass { 7 constructor(){ 8 console.log( this.CONST_VALUE_1 ); // インスタンスからアクセス 9 console.log( MyClass.CONST_VALUE_1 ); // スタティックにアクセス 10 } 11}; 12 13Object.defineProperties( MyClass, myConstants ); 14Object.defineProperties( MyClass.prototype, myConstants ); 15 16// 以下、テスト 17let myClass = new MyClass(); 18myClass.CONST_VALUE_1 = 3; // 書き換えを試みる 19console.log(myClass.CONST_VALUE_1); // インスタンスからアクセス 20// => 1 21MyClass.CONST_VALUE_1 = 3; // 書き換えを試みる 22console.log(MyClass.CONST_VALUE_1); // スタティックにアクセス 23// => 1

投稿2020/07/21 01:13

編集2020/07/21 11:12
AkitoshiManabe

総合スコア5434

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

anndonut

2020/07/21 10:29

defineObjectProperty()はObject.defineProperties()ですね。
torimingo

2020/07/21 10:48 編集

「どのインスタンスにも共通の値を持つ」というのはstatic?のことでしょうか?
AkitoshiManabe

2020/07/21 11:09

Object.HOGE でアクセスできる値があっても、 新しいオブジェクト oj の プロパティ HOGE としてアクセスするには、[[Prototype]] にもプロパティを定義する必要があります。 前者をstatic と表現しています。 2行の defineProperties() のうち、片方をコメントにして実行すると解っていただけるはずです。
AkitoshiManabe

2020/07/21 11:13

> anndonut さん、ご指摘ありがとうございます。 アンカーテキスト修正しました。
guest

0

クラスの中身をイミュータブルにするにはObject.freeze()を使えばいいらしいです。

JavaScriptでイミュータブルなプログラミングをする
(…ああなつかしい御仁が…)

html

1<html> 2<head> 3</head> 4 5<body> 6 7<script> 8 9class Cat 10{ 11 NAME = ""; 12 constructor(name) 13 { 14 this.NAME = name; 15 Object.freeze(this); 16 } 17 18 nya() 19 { 20 console.log(this.NAME); 21 } 22} 23 24let cat = new Cat("kuro"); 25 26cat.nya(); 27 28</script> 29</body> 30</html>

現行のECMAScript(JavaScript)ではプライベートフィールドが仕様に盛り込まれていないのでインスタンスをカプセル化するのはちょっと難しいみたいです(近いうちに実装されると思います)。なのでクラスのフィールドを一部書き換え不能にしたい場合はフィールドでクラス分けしてObject.freeze()をかけるといいと思います。

投稿2020/07/20 15:16

anndonut

総合スコア667

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torimingo

2020/07/20 15:31 編集

ご回答をありがとうございます。 ご提示頂いたプログラムの「NAME = "";」を削除しても動いたのですが、問題ありますでしょうか。 また、Object.freeze(this);以降は、他の変数も変更不可になりませんでしょうか・・・?
anndonut

2020/07/20 15:39

すみません、NAME = "";を削除した場合はフィールドではなくプロパティと呼ばれ、現行の仕様に即した使い方なのでOKです。
torimingo

2020/07/20 23:27

NAME = "";を削除しても大丈夫な件、了解です。 Object.freeze(this);以降は、他のプロパティも変更不可になってしまいませんでしょうか・・・?
anndonut

2020/07/21 10:17

なります。Object.defineProperty()を使うほうがスマートに行くと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問