JSのクラスについての質問

このQ&Aのポイント
  • JSのクラスについての質問。クラスの記述やインスタンスの作成方法について疑問があります。
  • クラスの記述方法やインスタンスの作成方法は初心者なのでよくわかりません。具体的には、constructorとnew演算子の関係について教えて欲しいです。
  • 引数を持つconstructorとnew演算子の関係がわかりません。インスタンスの作成時に引数を渡すとどのように処理されるのか教えてください。
回答を見る
  • ベストアンサー

JSのクラスについての質問

JSのクラスについての質問 ソース class Cat { constructor(name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } //インスタンス作成 var clsObj = new Cat("my cat"); //インスタンス(オブジェクト)の中身を出力 console.log(clsObj); 初心者なのでこの中のどの記述が必須で、 またnameはどれと対になっているかがわかりません。 インスタンスはnew クラス名 となっている所で作成されて変数に作られたインスタンスが代入されるというのは何となく分かったのですが、 console.log(clsObj); VM793:9 Cat {name: "my cat"} となるのがいまいちわかりません。 new Cat("my cat");は class Cat { constructor(name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } を実行するという事で、 引数は constructor(name) new Cat("my cat"); が対になっているのでnameがmycatに代わるという事でしょうか? new Cat("my cat");が実行された結果がインスタンスという事ですが、 mycatがインスタンスなのですか? 大変恐縮ですが、簡単に一連の流れを教えていただければ幸いです。 class Cat { constructor(name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } にどう渡されてどのように処理され何がインスタンスとして吐き出されるのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.8

>回答No.7 amanojaku1 >>そして定義の引数が仮引数つまりローカル変数の変数名に当たるという事も関数と同じですね。 >仮引数とローカル変数(プロパティー)とは違います。 >ローカル変数(プロパティー)はクラスの箱の中に定義されるモノです(添付画像参照)。 申し訳ございません訂正です、引数を引数としか考えてませんでしたが、ローカルと言われれば確かに引数もローカル変数でした。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ちなみに(コンストラクター以外は)クラスの構造がインスタンスの構造に反映されます(添付画像参照)。

htmlcss123
質問者

お礼

>>> >するとCat.nameとなりCatクラスという箱の中に入っているnameプロパティ?いや引数という事なのでしょうか? 引数ではなくプロパティです、ここではクラス内部のローカル変数と説明しているモノです(初心者に分かりやすいか どうかは別としてプロパティと言った方が正確ですね)。 関数内部(関数が持っている)のローカル変数は ご存知ですか?、それに類似しています、この場合はクラス内部(クラスが持っている)のローカル変数と言うイメージです。 Cat.nameとなりCatクラスという箱の中に入っているnameプロパティなのですね。 nameとコンストラクタの引数があるのでthis.nameのnameも引数なのかと思ったのですが、ドットつながりなのでcatクラス(オブジェクト)の中にあるnameプロパティ という事ですね。 関数のスコープの中で宣言する変数のことですよね。 巻き上げが起こる変数ですね。 これとクラス内の変数はほぼ同じ挙動をするという事ですか? するとスコープがクラスにもあるのでしょうか? 巻き上げも >>> >なぜこの例えはこんなわかりにくいことをしたんですかね? 恐らく同じ名前でも「this.」が付いてるか付いてないかで区別できるので、同じ名前でもコンフリクト(衝突、競合)せずに使えると言う例を示したかったのかもしれません。 thisで別の引数?の物と区別できるという事を伝えたかったのですね。 ただ二つはコンストラクタの引数でthis.nameだけはそもそも引数ではなくプロパティなので、 仮にかぶっても問題ないのでしょうね。 >>> >変数と似ている箱で 変数と違う箱と考えて下さい。 オブジェクト、クラス、関数、変数などいろいろな箱がありこんがらがるのですが、 もしかしてこれらはすべて変数なのですか? つまり箱はすべて変数で、これらは少し個性の違う変数なのでしょうか? >>> >特殊な箱でなんでも好きに入れ替えできず、 >入れられるものと入っていなくても良いものが固定されている箱という事でしょうか? >つまり変数と違ってコンストラクタが絶対に入っている箱なのですね。 初期設定が必要ないなら、コンストラクタは必要ないようです。 クラスをインスタンス化したい場合のみコンストラクタは必要で、 インスタンス化が不要なクラスなら必要ないという事でしょうか? ただクラスはインスタンス化しないと利用できないので、 文法上はコンストラクタなしでも良いが、実際はそのようなことはあり得ないという事でよいでしょうか? またインスタンス化と初期設定の違いが判らないのですが、イコールと考えてよいでしょうか? >>> >入れられないものもあるのですか? クラス内クラスは無理なようです。 それ以外はオブジェクトのように入れられるのですね。 >>> >var コンストラクターの「name」= my cat;という事ですかね? その説明は変な感じです、実際のプロセスを考えて下さい(「my cat」ではなく"my cat"文字列です)。 new Cat("my cat") ←ここでコンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれます。 constructor(name) {this.name = name} とは constructor関数の中に中カッコ内の式があり、 catクラス内のnameプロパティにconstructorの引数nameを代入するという事ですよね。 不思議なのはconstructorの引数nameを代入する部分なのですが関数の引数を代入するというのは初めて見ました。 仮引数nameなので constructor(name) { var name = "my cat"; this.name = name } という事ですよね。 つまり下記のcatクラスの引数が実引数になるという事ですよね。 //インスタンス作成 var clsObj = new Cat("my cat"); 関数であれば関数の呼び出しにある引数が実引数として代入されますが、 クラスの場合はconstructor関数の呼び出しにある引数ではなく クラスのインスタンス化にある引数が実引数として代入されるというルールなのですね。 constructor関数の呼び出しがないのが不思議でしたが、 constructor関数は定義するだけで呼び出しはしなくても実行されて、インスタンスを作成するのですね。 そして constructor(name) { var name = "my cat"; this.name = "my cat" } となりプロパティnameに文字列mycatが代入されるのですね。 >>> 「インスタンスの引数」と言うのは違います。 new Cat("my cat"):Catクラスに実引数"my cat"文字列を設定しnewすると、コンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれ、インスタンスが生成されます。 こちらも上記の説明で正しいでしょうか? >>> コンストラクターが在る場合もコンストラクターは初期設定だけです。 クラス"設計図"からインスタンス"実態"を作成すると言う事で、例えるなら十徳ナイフの"設計図"から十徳ナイフの"実態"を作成すると言うイメージして下さい。 (十徳ナイフの"実態"を作成しても)十徳ナイフが置いてあるだけでは何も役に立ちません、十徳ナイフは使ってこそ役に立つ訳です、例えば十徳ナイフの「栓抜き」(機能)を使うと言うのが「栓抜き」メソッド、「缶切」(機能)を使うと言うのが「缶切」メソッドに対応すると言うイメージです。 なるほどクラスがナイフの設計図で、constructor、newクラス名がナイフを作るための作業で、 ナイフがインスタンス化されたオブジェクトですが、この時点では何のメリットもないのですね。 インスタンス化されたオブジェクトを使う作業がメソッドという事ですね。 下記例ですとnew Cat("my cat");がナイフを具現化する作業(constructorもこれに当たる?)で、 実際に使うメソッドはここにはないのですかね? class Cat { (name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } //インスタンス作成 var clsObj = new Cat("my cat"); //インスタンス(オブジェクト)の中身を出力 console.log(clsObj); >>> 仮引数とローカル変数(プロパティー)とは違います。 ローカル変数(プロパティー)はクラスの箱の中に定義されるモノです(添付画像参照)。 上記でも記載した、仮引数と実引数が実質var name = "my cat";というローカル関数と同じ結果になるという意味で書いたのですが、 それでも違うでしょうか? もちろん同じものではないですが、実質同じ結果にはなるのですよね。 >>> そして constructor(name) { var name = "my cat"; this.name = "my cat" } となりプロパティnameに文字列mycatが代入されるのですね。 下記が同じ結果になるという意味なのでしょうね。 >>> 申し訳ございません訂正です、引数を引数としか考えてませんでしたが、ローカルと言われれば確かに引数もローカル変数でした。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ちなみに(コンストラクター以外は)クラスの構造がインスタンスの構造に反映されます(添付画像参照)。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ここがよくわからないのですがconstructor(name)のnameは引数ではなくプロパティなのですか? 見た目は引数に見えますが、違いとしてはプロパティは値が入れられる箱であり、 仮引数はローカル変数名でしかなく、ローカル変数そのものではないので、箱ではなく、値を入れられないのですかね?

その他の回答 (8)

回答No.9

>回答No.8 amanojaku1 >>仮引数とローカル変数(プロパティー)とは違います。 >>ローカル変数(プロパティー)はクラスの箱の中に定義されるモノです(添付画像参照)。 >申し訳ございません訂正です、引数を引数としか考えてませんでしたが、ローカルと言われれば確かに引数もローカル変数でした。 さらに訂正です、引数は関数内からみるとローカル変数ですが、関数外との接点を持っている(関数外のデータを持って来れる)性質もあるので、普通のローカル変数とは別と考えた方が良いでしょう。

htmlcss123
質問者

お礼

引数からできるローカル変数は、ただのローカル変数ではなく、スコープ外の情報も参照できるローカル変数という事ですね。

回答No.7

>同じnameなのに違うとはどう区別したのですか? constructor(name) {this.name = name} ↑この行で2つ記述されている「name」が「constructor」の仮引数で、「this.name」がクラス内部のローカル変数(その実態は内部的に「name」なのですが、コンストラクターの「name」仮引数とは別物です) つまり(class内の定義の場合)「this.」が付いてるか付いてないかで区別できます。 class内の定義でない場合、「Cat」クラス内部の「name」ローカル変数にアクセスする場合は(インスタンスが「clsObj」の場合)「clsObj.name」ど言うシンタックスでアクセスできます。 >this.name以外のname引数はconstractorの引数という事ですね。 そうです。 >区別できるように「this.name」となってますというのがいまいちよくわからないのですが、 >thisはクラスcatのことですよね。 そうです。 >するとCat.nameとなりCatクラスという箱の中に入っているnameプロパティ?いや引数という事なのでしょうか? 引数ではなくプロパティです、ここではクラス内部のローカル変数と説明しているモノです(初心者に分かりやすいか どうかは別としてプロパティと言った方が正確ですね)。 関数内部(関数が持っている)のローカル変数は ご存知ですか?、それに類似しています、この場合はクラス内部(クラスが持っている)のローカル変数と言うイメージです。 >ふつう違うなら別名にしますよね? そうですね。 >なぜこの例えはこんなわかりにくいことをしたんですかね? 恐らく同じ名前でも「this.」が付いてるか付いてないかで区別できるので、同じ名前でもコンフリクト(衝突、競合)せずに使えると言う例を示したかったのかもしれません。 >変数と似ている箱で 変数と違う箱と考えて下さい。 >特殊な箱でなんでも好きに入れ替えできず、 >入れられるものと入っていなくても良いものが固定されている箱という事でしょうか? >つまり変数と違ってコンストラクタが絶対に入っている箱なのですね。 初期設定が必要ないなら、コンストラクタは必要ないようです。 >メソッドなども必須なのですか? メソッドも必要ないなら、メソッドを記述する必要はありません。 >入れられないものもあるのですか? クラス内クラスは無理なようです。 >>>クラス内の関数定義はfunctionは省略できる、省略しなければいけないのですね。 >>>恐らくこれはクラス内の関数だよと区別するためですかね? >>この場合、分かりきっているのでワザワザ書く必要もないと言う事で、省力化しているのだと思われます。 >書いてはいけないのではなく省略可能なので省略しているのですね。 >ただ一般的な関数も省略可能でしたっけ? 省略可能と言う意味ではありません、分かりきっているのでワザワザ書く必要もないので「書いてはいけない」と言う仕様にして省力化している、と言う事です。 >var コンストラクターの「name」= my cat;という事ですかね? その説明は変な感じです、実際のプロセスを考えて下さい(「my cat」ではなく"my cat"文字列です)。 new Cat("my cat") ←ここでコンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれます。 >new Cat("my cat")の部分がインスタンスの作成ですが >関数で例えるならこちらは定義した関数の呼び出しに当たるのですかね。 コンストラクターが無い場合も有り得るので「関数の呼び出しに当たる」とも言えませんし、コンストラクターが在る場合もコンストラクターは初期設定だけです。 クラス"設計図"からインスタンス"実態"を作成すると言う事で、例えるなら十徳ナイフの"設計図"から十徳ナイフの"実態"を作成すると言うイメージして下さい。 (十徳ナイフの"実態"を作成しても)十徳ナイフが置いてあるだけでは何も役に立ちません、十徳ナイフは使ってこそ役に立つ訳です、例えば十徳ナイフの「栓抜き」(機能)を使うと言うのが「栓抜き」メソッド、「缶切」(機能)を使うと言うのが「缶切」メソッドに対応すると言うイメージです。 >インスタンスの引数が実引数なら関数も呼び出しが実引数ですよね。 >ローカル変数に代入される値がインスタンスの引数になり、関数と同じですね。 「インスタンスの引数」と言うのは違います。 new Cat("my cat"):Catクラスに実引数"my cat"文字列を設定しnewすると、コンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれ、インスタンスが生成されます。 >そして定義の引数が仮引数つまりローカル変数の変数名に当たるという事も関数と同じですね。 仮引数とローカル変数(プロパティー)とは違います。 ローカル変数(プロパティー)はクラスの箱の中に定義されるモノです(添付画像参照)。

htmlcss123
質問者

お礼

お返事ありがとうございます。 じっくり見させていただきますのでお待ちください

回答No.6

>classも変数と同じ箱で中に関数や変数を入れられるのですね。 >其れってオブジェクトと同じ箱という事ですか? 変数とは違います、変数のように自由に値を代入できる訳ではありません。 classとは"設計図"の"定義"であり、そして構造をもってます(添付画像参照)。 今回は コンストラクター1個。 変数1個:「this.name」(その実態は内部的に「name」なのですが、コンストラクターの「name」パラメータとは別物です)。 メソッド1個:「meow()」メソッド。 となります。 >>class Cat { ←「Cat」クラス定義。 >Catという名前のクラスを定義する そうです。 >オブジェクトの定義と同じですね。 オブジェクトと言う言葉は実は曖昧で、通常インスタンス(実態)を表します(オブジェクト指向と言った場合は また別ですが)。 そう言う意味で言うとインスタンス(実態)ではありません。 >クラス内の関数定義はfunctionは省略できる、省略しなければいけないのですね。 >恐らくこれはクラス内の関数だよと区別するためですかね? この場合、分かりきっているのでワザワザ書く必要もないと言う事で、省力化しているのだと思われます。 >関数の定義で例えるならfunction Cat(){}と全く同じですね。 まあ確かに("定義"と言う)見た目は似ていますが…。 >コンストラクタとは設計図のクラスをインスタンス化するための関数をコンストラクタと特別に言っているだけの関数そのものなので、 >functionがconstracutorになっただけで他は関数と全く同じなのですね そうですね。 >>「this.name = name」はコンストラクターの「name」パラメータをクラス内部のローカル変数「this.name」(その実態は内部的に「name」なのですが、 >>コンストラクターの「name」パラメータとは別物です)に >>meow() {alert( this.name + 'はミャオと鳴きました' )} ←「meow()」メソッド定義。 >} >ここがよくわかりませんでした。 >this.name = nameとは変数の定義の事なのでしょうか? 分かりにくいですが 「name」が仮引数。 「this.name」が「Cat」クラス内部のローカル変数(その実態は内部的に「name」なのですが、コンストラクターの「name」パラメータとは別物です、区別できるように「this.name」となってます)。 >コンストラクターの「name」パラメータは仮引数と思うのですが実引数はどこにあるのでしょうか? 実引数はインスタンス作成時にセットされてます、下記「"my cat"」文字列が実引数で、コンストラクターの「name」仮引数に代入されます。 //インスタンス作成 var clsObj = new Cat("my cat"); // 「new Cat(~)」で(コンストラクターが呼ばれ)インスタンスが作成される、そのインスタンスを「clsObj」変数に代入。

htmlcss123
質問者

お礼

>>> 変数とは違います、変数のように自由に値を代入できる訳ではありません。 classとは"設計図"の"定義"であり、そして構造をもってます(添付画像参照)。 今回は コンストラクター1個。 変数1個:「this.name」(その実態は内部的に「name」なのですが、コンストラクターの「name」パラメータとは別物です)。 メソッド1個:「meow()」メソッド。 となります。 nameは同じnameなのに、別物なのですね。非常にややこしい例えを採用してしまったのですかね? 同じnameなのに違うとはどう区別したのですか? なぜこの例えはこんなわかりにくいことをしたんですかね? ふつう違うなら別名にしますよね? 変数と似ている箱ですが、 特殊な箱でなんでも好きに入れ替えできず、 入れられるものと入っていなくても良いものが固定されている箱という事でしょうか? つまり変数と違ってコンストラクタが絶対に入っている箱なのですね。 メソッドなども必須なのですか? 入れられないものもあるのですか? >>> >オブジェクトの定義と同じですね。 オブジェクトと言う言葉は実は曖昧で、通常インスタンス(実態)を表します(オブジェクト指向と言った場合は また別ですが)。 そう言う意味で言うとインスタンス(実態)ではありません。 プリミティブ以外はすべてオブジェクトと聞いているのですが、インスタンスはオブジェクトではないのですか? >>> >クラス内の関数定義はfunctionは省略できる、省略しなければいけないのですね。 >恐らくこれはクラス内の関数だよと区別するためですかね? この場合、分かりきっているのでワザワザ書く必要もないと言う事で、省力化しているのだと思われます。 書いてはいけないのではなく省略可能なので省略しているのですね。 ただ一般的な関数も省略可能でしたっけ? >>> >ここがよくわかりませんでした。 >this.name = nameとは変数の定義の事なのでしょうか? 分かりにくいですが 「name」が仮引数。 「this.name」が「Cat」クラス内部のローカル変数(その実態は内部的に「name」なのですが、コンストラクターの「name」パラメータとは別物です、 区別できるように「this.name」となってます)。 区別できるように「this.name」となってますというのがいまいちよくわからないのですが、 thisはクラスcatのことですよね。 するとCat.nameとなりCatクラスという箱の中に入っているnameプロパティ?いや引数という事なのでしょうか? this.name以外のname引数はconstractorの引数という事ですね。 >>> >コンストラクターの「name」パラメータは仮引数と思うのですが実引数はどこにあるのでしょうか? 実引数はインスタンス作成時にセットされてます、下記「"my cat"」文字列が実引数で、コンストラクターの「name」仮引数に代入されます。 //インスタンス作成 var clsObj = new Cat("my cat"); // 「new Cat(~)」で(コンストラクターが呼ばれ)インスタンスが作成される、そのインスタンスを「clsObj」変数に代入。 つまり var コンストラクターの「name」= my cat;という事ですかね? 上記の質問で考えると間違っているかもしれませんが、 すると実質 class Cat { var name = my cat; constructor(name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } となるという事でよいでしょうか? 本当に関数そっくりですね。 new Cat("my cat")の部分がインスタンスの作成ですが 関数で例えるならこちらは定義した関数の呼び出しに当たるのですかね。 インスタンスの引数が実引数なら関数も呼び出しが実引数ですよね。 ローカル変数に代入される値がインスタンスの引数になり、関数と同じですね。 そして定義の引数が仮引数つまりローカル変数の変数名に当たるという事も関数と同じですね。

回答No.5

>class Cat { ←「Cat」クラス定義。 >関数の定義で例えるならfunction Cat()のようなものですね。 違います、class と言う箱の中に、関数(コンストラクター、(0個以上の複数の)メソッド)、(0個以上の複数の)変数を詰め込むと言うイメージです(カプセル化と言われたりします)。 >Catという名前のクラスを定義するよという事ですね。 class 内に関数(コンストラクター、(0個以上の複数の)メソッド)、(0個以上の複数の)変数を定義できます。 >meow()は関数の呼び出しという事ですが、定義が見つかりません。 >どこで定義しているのでしょうか? >それともfunctionの省略した定義がここなのでしょうか? >ソースには見つかりませんでしたが、どこかにあるのですかね? どうも class 内の関数の定義には「function」は記述する必要はない用です。 もう1度 下記のコメントを良く見て下さい。 『「Cat」クラス定義』内に『コンストラクター定義(new 時に実行される)』、『「meow()」メソッド定義』とコメントで明記しています。 class Cat { // 「Cat」クラス定義。 constructor(name) {this.name = name} // コンストラクター定義(new 時に実行される)。 meow() {alert( this.name + 'はミャオと鳴きました' )} // 「meow()」メソッド定義。 }

htmlcss123
質問者

お礼

>>>> >class Cat { ←「Cat」クラス定義。 >関数の定義で例えるならfunction Cat()のようなものですね。 違います、class と言う箱の中に、関数(コンストラクター、(0個以上の複数の)メソッド)、(0個以上の複数の)変数を詰め込むと言うイメージです(カプセル化と言われたりします) classも変数と同じ箱で中に関数や変数を入れられるのですね。 其れってオブジェクトと同じ箱という事ですか? >>> Catという名前のクラスを定義する オブジェクトの定義と同じですね。 >>> どうも class 内の関数の定義には「function」は記述する必要はない用です。 もう1度 下記のコメントを良く見て下さい。 『「Cat」クラス定義』内に『コンストラクター定義(new 時に実行される)』、『「meow()」メソッド定義』とコメントで明記しています。 クラス内の関数定義はfunctionは省略できる、省略しなければいけないのですね。 恐らくこれはクラス内の関数だよと区別するためですかね? 下記二つはどうでしょうか?このnameの対が一番わかりませんのでお願いします。 >>> 「this.name = name」はコンストラクターの「name」パラメータをクラス内部のローカル変数「this.name」(その実態は内部的に「name」なのですが、 コンストラクターの「name」パラメータとは別物です)に meow() {alert( this.name + 'はミャオと鳴きました' )} ←「meow()」メソッド定義。 } ここがよくわかりませんでした。 this.name = nameとは変数の定義の事なのでしょうか? コンストラクターの「name」パラメータは仮引数と思うのですが実引数はどこにあるのでしょうか? >>> 「new Cat("my cat")」は「constructor(name) {this.name = name}」コンストラクターだけが実行されます。 「clsObj.meow();」とすれば「meow()」メソッドが実行されると思われます。 new Cat("my cat")が実行されたときにクラス内の constructor(name) {this.name = name}の部分だけが実行されるという事ですか? つまりnew クラス名(引数)とは初めに定義したクラスを実行しろ、呼び出ししろという意味で。 その際にconstructor(name) {this.name = name} のみが実行されるのですかね? よって関数と同じで、new Cat("my cat")のmycatが実引数で、constructor(name)のnameが仮引数となるのですか? >>> constructor(name) {this.name = name} ←コンストラクター定義(new 時に実行される) 関数の定義で例えるならfunction Cat(){}と全く同じですね。 コンストラクタとは設計図のクラスをインスタンス化するための関数をコンストラクタと特別に言っているだけの関数そのものなので、 functionがconstracutorになっただけで他は関数と全く同じなのですね。 >>> 「this.name = name」はコンストラクターの「name」パラメータをクラス内部のローカル変数「this.name」(その実態は内部的に「name」なのですが、 コンストラクターの「name」パラメータとは別物です)に meow() {alert( this.name + 'はミャオと鳴きました' )} ←「meow()」メソッド定義。 } ここがよくわかりませんでした。 this.name = nameとは変数の定義の事なのでしょうか? コンストラクターの「name」パラメータは仮引数と思うのですが実引数はどこにあるのでしょうか?

回答No.4

回答No.3 amanojaku1 >この中のどの記述が必須 とりあえず下記が基本です、「meow()」メソッドの実行はプログラマーが呼びたい時に呼べば良いので、本当の意味での必須と言う訳ではありません(つまり必要がなければ「meow()」メソッドは呼ばなくても良い)。 class Cat { // 「Cat」クラス定義。 constructor(name) {this.name = name} // コンストラクター定義(new 時に実行される) meow() {alert( this.name + 'はミャオと鳴きました' )} // 「meow()」メソッド定義。 } //インスタンス作成 var clsObj = new Cat("my cat"); // 「new Cat(~)」で(コンストラクターが呼ばれ)インスタンスが作成される、そのインスタンスを「clsObj」変数に代入。 clsObj.meow(); // 「meow()」メソッドを実行

htmlcss123
質問者

お礼

class Cat { constructor(name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } //インスタンス作成 var clsObj = new Cat("my cat"); //インスタンス(オブジェクト)の中身を出力 console.log(clsObj); class Cat { ←「Cat」クラス定義。 関数の定義で例えるならfunction Cat()のようなものですね。 Catという名前のクラスを定義するよという事ですね。 meow()は関数の呼び出しという事ですが、定義が見つかりません。 どこで定義しているのでしょうか? それともfunctionの省略した定義がここなのでしょうか? ソースには見つかりませんでしたが、どこかにあるのですかね?

回答No.3

以前のJSのオブジェクト指向プログレミングは非常に分かりにくい、と言うか理解しようと言う気持ちが沸いてこないモノでしたが、今回のような新しい?オブジェクト指向の記述はJavaに類似していて分かりやすいです(あくまで当方の個人的な主観ですが)。 class Cat { ←「Cat」クラス定義。 constructor(name) {this.name = name} ←コンストラクター定義(new 時に実行される)、「this.name = name」はコンストラクターの「name」パラメータをクラス内部のローカル変数「this.name」(その実態は内部的に「name」なのですが、コンストラクターの「name」パラメータとは別物です)に meow() {alert( this.name + 'はミャオと鳴きました' )} ←「meow()」メソッド定義。 } //インスタンス作成 var clsObj = new Cat("my cat"); ←「new Cat("my cat")」でインスタンスを作成し、そのインスタンスをclsObj変数に代入。 //インスタンス(オブジェクト)の中身を出力 console.log(clsObj); ←インスタンス(オブジェクト)の中身をConsole(コンソール)に出力。 console.log(clsObj); VM793:9 ←これは良く分かりませんが その数字はスクリプトIDらしいです。 Cat {name: "my cat"} ←インスタンス(オブジェクト)の中身です、この「name」とはコンストラクター中にあった「this.name」であり、コンストラクターの「name」パラメータではありません。 >new Cat("my cat");は >class Cat { >constructor(name) {this.name = name} >meow() {alert( this.name + 'はミャオと鳴きました' )} >} >を実行するという事で、 違います 「new Cat("my cat")」は「constructor(name) {this.name = name}」コンストラクターだけが実行されます。 「clsObj.meow();」とすれば「meow()」メソッドが実行されると思われます。 >引数は >constructor(name) >new Cat("my cat"); >が対になっているのでnameがmycatに代わるという事でしょうか? この「name」はコンストラクターのパラメータです、コンストラクターのパラメータ「name」変数に"my cat"文字列が代入されます。

htmlcss123
質問者

お礼

class Cat { constructor(name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } //インスタンス作成 var clsObj = new Cat("my cat"); //インスタンス(オブジェクト)の中身を出力 console.log(clsObj); class Cat { ←「Cat」クラス定義。 関数の定義で例えるならfunction Cat()のようなものですね。 Catという名前のクラスを定義するよという事ですね。 >>> constructor(name) {this.name = name} ←コンストラクター定義(new 時に実行される) 関数の定義で例えるならfunction Cat(){}と全く同じですね。 コンストラクタとは設計図のクラスをインスタンス化するための関数をコンストラクタと特別に言っているだけの関数そのものなので、 functionがconstracutorになっただけで他は関数と全く同じなのですね。 >>> 「this.name = name」はコンストラクターの「name」パラメータをクラス内部のローカル変数「this.name」(その実態は内部的に「name」なのですが、 コンストラクターの「name」パラメータとは別物です)に meow() {alert( this.name + 'はミャオと鳴きました' )} ←「meow()」メソッド定義。 } ここがよくわかりませんでした。 this.name = nameとは変数の定義の事なのでしょうか? コンストラクターの「name」パラメータは仮引数と思うのですが実引数はどこにあるのでしょうか? >>> meow() {alert( this.name + 'はミャオと鳴きました' )} これはただの一般的なmeowという名前の関数を定義しただけという事ですね。 functionがないのは省略可能なのですか? >>> /インスタンス作成 var clsObj = new Cat("my cat"); ←「new Cat("my cat")」でインスタンスを作成し、そのインスタンスをclsObj変数に代入。 catクラスに文字列を渡してインスタンス化をするといったいどうなるのでしょうか? 全く想像がつきません? my catはnameと対になっているのですか? var cat = mycat と同じことになるのですか? newで出来上がったインスタンスをclsobj変数に代入しているんですよね? するとconsoleは出来上がったインスタンスを表記しているのではないのですか? ・ class Cat { constructor(仮引数) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } //インスタンス作成 var clsObj = new Cat(実引数) という事ですか?; >>> 「new Cat("my cat")」は「constructor(name) {this.name = name}」コンストラクターだけが実行されます。 「clsObj.meow();」とすれば「meow()」メソッドが実行されると思われます。 new Cat("my cat")が実行されたときにクラス内の constructor(name) {this.name = name}の部分だけが実行されるという事ですか? つまりnew クラス名(引数)とは初めに定義したクラスを実行しろ、呼び出ししろという意味で。 その際にconstructor(name) {this.name = name} のみが実行されるのですかね? よって関数と同じで、new Cat("my cat")のmycatが実引数で、constructor(name)のnameが仮引数となるのですか?

  • b0a0a
  • ベストアンサー率49% (156/313)
回答No.2

間違えました Cat = 『constructor』 『constructor』.prototype = {constructor:function constructor(name) {this.name = name},meow:function meow() {alert( this.name + 'はミャオと鳴きました' )}} です。

  • b0a0a
  • ベストアンサー率49% (156/313)
回答No.1

『Cat {name: "my cat"}』 はそれがCatクラスのインスタンスであり、nameプロパティに"my cat"を持つオブジェクトということを表しています。 クラス名を呼ぶとconstructorが呼ばれることになり、nameがmycatに代わるというのはあっています。 そしてmycatがインスタンスです。 「インスタンス」と言うのは「実体」という意味です。 つまり、「抽象」的に見れる型を用いて作られた「実体」のオブジェクトなのです。 一連の流れをざっくり簡略化して書くと、 まずClass構文でCatという名前でクラスが定義されるとき、 構文内のconstructor関数がCatになります。 つまり、Cat == constructorです このとき、constructorのprototypeプロパティに、構文内の関数達、constructorやmeowメソッドが入ります。 つまり Cat = 『constructor』 = {constructor:function constructor(name) {this.name = name},meow:function meow() {alert( this.name + 'はミャオと鳴きました' )}} です。 次にCatクラスがnew演算子で呼ばれると、new演算子の効果で、 Cat.prototypeを「「プロトタイプ」」としたオブジェクトが生成され、Catにthisとして渡され呼ばれます。 そしてCatを実行し終わったあと、処理された、ここではnameプロパティを追加されたオブジェクトを new演算子は結果として返すのです。

関連するQ&A

  • JSのクラスについて

    JSのクラスについて https://okwave.jp/qa/q9320085.html の続き >>> >するとCat.nameとなりCatクラスという箱の中に入っているnameプロパティ?いや引数という事なのでしょうか? 引数ではなくプロパティです、ここではクラス内部のローカル変数と説明しているモノです(初心者に分かりやすいか どうかは別としてプロパティと言った方が正確ですね)。 関数内部(関数が持っている)のローカル変数は ご存知ですか?、それに類似しています、この場合はクラス内部(クラスが持っている)のローカル変数と言うイメージです。 Cat.nameとなりCatクラスという箱の中に入っているnameプロパティなのですね。 nameとコンストラクタの引数があるのでthis.nameのnameも引数なのかと思ったのですが、ドットつながりなのでcatクラス(オブジェクト)の中にあるnameプロパティ という事ですね。 関数のスコープの中で宣言する変数のことですよね。 巻き上げが起こる変数ですね。 これとクラス内の変数はほぼ同じ挙動をするという事ですか? するとスコープがクラスにもあるのでしょうか? 巻き上げも >>> >なぜこの例えはこんなわかりにくいことをしたんですかね? 恐らく同じ名前でも「this.」が付いてるか付いてないかで区別できるので、同じ名前でもコンフリクト(衝突、競合)せずに使えると言う例を示したかったのかもしれません。 thisで別の引数?の物と区別できるという事を伝えたかったのですね。 ただ二つはコンストラクタの引数でthis.nameだけはそもそも引数ではなくプロパティなので、 仮にかぶっても問題ないのでしょうね。 >>> >変数と似ている箱で 変数と違う箱と考えて下さい。 オブジェクト、クラス、関数、変数などいろいろな箱がありこんがらがるのですが、 もしかしてこれらはすべて変数なのですか? つまり箱はすべて変数で、これらは少し個性の違う変数なのでしょうか? >>> >特殊な箱でなんでも好きに入れ替えできず、 >入れられるものと入っていなくても良いものが固定されている箱という事でしょうか? >つまり変数と違ってコンストラクタが絶対に入っている箱なのですね。 初期設定が必要ないなら、コンストラクタは必要ないようです。 クラスをインスタンス化したい場合のみコンストラクタは必要で、 インスタンス化が不要なクラスなら必要ないという事でしょうか? ただクラスはインスタンス化しないと利用できないので、 文法上はコンストラクタなしでも良いが、実際はそのようなことはあり得ないという事でよいでしょうか? またインスタンス化と初期設定の違いが判らないのですが、イコールと考えてよいでしょうか? >>> >入れられないものもあるのですか? クラス内クラスは無理なようです。 それ以外はオブジェクトのように入れられるのですね。 >>> >var コンストラクターの「name」= my cat;という事ですかね? その説明は変な感じです、実際のプロセスを考えて下さい(「my cat」ではなく"my cat"文字列です)。 new Cat("my cat") ←ここでコンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれます。 constructor(name) {this.name = name} とは constructor関数の中に中カッコ内の式があり、 catクラス内のnameプロパティにconstructorの引数nameを代入するという事ですよね。 不思議なのはconstructorの引数nameを代入する部分なのですが関数の引数を代入するというのは初めて見ました。 仮引数nameなので constructor(name) { var name = "my cat"; this.name = name } という事ですよね。 つまり下記のcatクラスの引数が実引数になるという事ですよね。 //インスタンス作成 var clsObj = new Cat("my cat"); 関数であれば関数の呼び出しにある引数が実引数として代入されますが、 クラスの場合はconstructor関数の呼び出しにある引数ではなく クラスのインスタンス化にある引数が実引数として代入されるというルールなのですね。 constructor関数の呼び出しがないのが不思議でしたが、 constructor関数は定義するだけで呼び出しはしなくても実行されて、インスタンスを作成するのですね。 そして constructor(name) { var name = "my cat"; this.name = "my cat" } となりプロパティnameに文字列mycatが代入されるのですね。 >>> 「インスタンスの引数」と言うのは違います。 new Cat("my cat"):Catクラスに実引数"my cat"文字列を設定しnewすると、コンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれ、インスタンスが生成されます。 こちらも上記の説明で正しいでしょうか? >>> コンストラクターが在る場合もコンストラクターは初期設定だけです。 クラス"設計図"からインスタンス"実態"を作成すると言う事で、例えるなら十徳ナイフの"設計図"から十徳ナイフの"実態"を作成すると言うイメージして下さい。 (十徳ナイフの"実態"を作成しても)十徳ナイフが置いてあるだけでは何も役に立ちません、十徳ナイフは使ってこそ役に立つ訳です、例えば十徳ナイフの「栓抜き」(機能)を使うと言うのが「栓抜き」メソッド、「缶切」(機能)を使うと言うのが「缶切」メソッドに対応すると言うイメージです。 なるほどクラスがナイフの設計図で、constructor、newクラス名がナイフを作るための作業で、 ナイフがインスタンス化されたオブジェクトですが、この時点では何のメリットもないのですね。 インスタンス化されたオブジェクトを使う作業がメソッドという事ですね。 下記例ですとnew Cat("my cat");がナイフを具現化する作業(constructorもこれに当たる?)で、 実際に使うメソッドはここにはないのですかね? class Cat { (name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } //インスタンス作成 var clsObj = new Cat("my cat"); //インスタンス(オブジェクト)の中身を出力 console.log(clsObj); >>> 仮引数とローカル変数(プロパティー)とは違います。 ローカル変数(プロパティー)はクラスの箱の中に定義されるモノです(添付画像参照)。 上記でも記載した、仮引数と実引数が実質var name = "my cat";というローカル関数と同じ結果になるという意味で書いたのですが、 それでも違うでしょうか? もちろん同じものではないですが、実質同じ結果にはなるのですよね。 >>> そして constructor(name) { var name = "my cat"; this.name = "my cat" } となりプロパティnameに文字列mycatが代入されるのですね。 下記が同じ結果になるという意味なのでしょうね。 >>> 申し訳ございません訂正です、引数を引数としか考えてませんでしたが、ローカルと言われれば確かに引数もローカル変数でした。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ちなみに(コンストラクター以外は)クラスの構造がインスタンスの構造に反映されます(添付画像参照)。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ここがよくわからないのですがconstructor(name)のnameは引数ではなくプロパティなのですか? 見た目は引数に見えますが、違いとしてはプロパティは値が入れられる箱であり、 仮引数はローカル変数名でしかなく、ローカル変数そのものではないので、箱ではなく、値を入れられないのですかね?

  • クラス内からインスタンス先の名前を参照する事は出来るのでしょうか

    クラス内からインスタンス先の名前を参照する事は出来るのでしょうか 例えば function hoge(){  this.dispname=function{   alert("xxxxx");  } } を  var fuga1=new hoge();  var fuga2=new hoge(); とインスタンスして、  fuga1.dispname();  fuga2.dispname(); とした時 xxxxにそれぞれ'fuga1'、'fuga2'といった名前 を取得してセットすることは可能でしょうか? 逆なら、  alert(fuga1.constructor.name); //Alerts "hoge"  alert(fuga1.constructor.name); //Alerts "hoge" と出来る。 ※インスタンスする時に名前を渡すしかないんでしょうか。  var fuga1=new hoge('fuga1');みたいに...

  • クラスのインスタンス名をクラス内で取得できますか?

    クラスのインスタンス名をクラス内で取得できますか? 今VC++6.0を使っています。例として下記のクラスのコンストラクタで CTest::CTest() { TRACE("%s",typeid(this).name()); } としておいて、 別なクラスで CTest testInst; を生成すると デバッグエリアに 「class CTest *」 と表示することはできました。 これが出来るのなら、インスタンス名 testInst をCTestクラスの内部から 取得することは出来ないのかと思ったのですが、 取得することは可能なのでしょうか?

  • スーパークラスの取得の仕方

    どなたかお知恵を貸してください。 現在抽象クラスを作って表示をさせる実験をしています。 ですが、下記ソースでは、取得したnameをが参照することができません。 どのようにすれば、たまの名前を出すことが出来るのでしょうか よろしくお願いいたします。 abstract class Mammals { /** 名前を表す */ String name; abstract public void introduceOneself(); public void setName(String name) { name = name; } } class Cat extends Mammals { public Cat() { super(); } public void introduceOneself() { System.out.println(name+"です。うにゃにゃ。"); } } class Main { public static void main (String[] args) { Cat tama = new Cat(); //コンストラクタ呼び出し Mammals neko = tama; //コンストラクタ呼び出し neko.setName("たま"); //自己紹介する tama.introduceOneself(); //自己紹介する } }

    • ベストアンサー
    • Java
  • [JS]setTimeoutでクラス関数を使いたい

    他の処理を待ってから、別の処理を実施したい場合に、setTimeoutを使用するのが 一般的だと思いますが、特定のクラスの関数を実行する方法がよくわかりません。 グローバル変数を使用する場合には以下で動きます。 ※待機の部分は、問題を簡略化するため今回は3回実行完了まで、としています。 counter = 0; max = 3; method(); function method(){ if ( counter < max ) { timerId = setTimeout(method, 10 ); console.log(counter); counter++; } else { console.log("done"); } } 出力は以下のとおり。 0 1 2 done methodやcounter, maxなどを隠蔽するため、クラス関数を作り、以下のようにしました。 a = new test(); a.method(); function test(){ this.counter = 0; this.max = 3; this.method = function(){ if ( this.counter < this.max ) { timerId = setTimeout(this.method, 10 ); console.log(this.counter); this.counter++; } else { console.log("done"); } } } 出力は以下のようになってしまい、意図したように実行できていません。 0 done このような場合、どのようにしてクラス関数を再呼び出しするのでしょうか。

  • Dimensionクラスの使い方

    Javaを始めたばかりの者です。 参考書を読みながら進めていて下記のソースコードで Dimensionクラスを使用している箇所で行き詰まりました。 使われていたのは、以下のコード --------------------------------------------------------------------------------------------------------------------- import java.awt.*; import javax.swing.*; import java.util.*; class xxx{  static public void main(String[] argv){  /*標準入力からmsgに文字列を入力*/  String msg = scan.next();  /*JLabelクラス型のオブジェクト型変数を作成し、インスタンスを生成*/  JLabel label = new JLabel(msg);  /*JLabelのインスタンスのコンストラクタに入力されたmsgのサイズを取得*/  Dimension dim = label.getPreferredSize();  ・・・etc  } } ---------------------------------------------------------------------------------------------------------------------- 自分が今まで使ってきたクラスは下記のような感じで使っていましたが、ここではnewしていない。 これは、どういうことなんでしょうか? クラス名 dim = new クラス名(); インスタンス作成 = コンストラクタの呼び出し。 new演算子はクラスのコンストラクタを呼び出している理解ですが Dimension dim = label.getPreferredSize(); 上記のコードではDimentionクラスのインスタンスは作られていないということだと思います。 ということは、 ここでは何をしているのでしょうか? どなたか、教えて下さい。

    • ベストアンサー
    • Java
  • オブジェクト指向について質問

    メインのクラスをインスタンスする際にコンストラクターに書かれている処理が実行されますが、オブジェクトが生成された時のイベントに書くのと、どのような違いがありますか? public partial class Form1 : Form{ public Form1()//コンストラクター {処理1} private void Form1_Load(object sender, EventArgs e)//インスタンス時のイベント {処理2} } また、別クラスの中でnewを使ってインスタンスがされ場合、コンストラクターと上記のイベントは同じように発生しますか? public class Form2{ Form1 = new Form1(); } よろしくおねがいします。

  • javascriptのObject()コンストラクタについて質問です。

    javascriptのObject()コンストラクタについて質問です。 var obj = new Object(); var obj2 = Object(); console.log(obj === obj2)//false いつも質問ばかり恐縮です。。。 どこかのサイトでこの2つは等価みたいな記事を読んだような気がするのですが、 ということはObjectコンストラクタでオブジェクトを作る際はnew演算子は要らない?? のでしょうか?? またobjとobj2の2つの違いを色々試したのですが違いがわかりません。new演算子を 付けたインスタンスと付けないインスタンス??の違いをどなたか ご教授いただけると助かります。

  • PHP5でクラスを作成しています。

    PHP5でクラスを作成しています。 コンストラクタの段階で論理エラーにしたくて、インスタンス値をnullにしたいです。 つまり直ちにプログラムを止めずに、クラスの生成(インスタンス化)を失敗させる 方法を__construct()関数内でどのように書けば良いのでしょうか? class Sample { function __construct() { // この中で処理の異常が発生! // インスタンス作成を失敗させる or インスタンス値をヌルにする。 //? //?どのように書けば?? //? } } $a = new Sample(); if ($a === null) { printf("正しくインスタンスの生成ができませんでした。"); } よろしくお願いします。

    • 締切済み
    • PHP
  • perlのクラスについて

    perlでクラスを作成しています。その際、コンストラクタnewで無名配列を定義して、funcメソッドで、この無名配列に値をいれるにはどうすればよいでしょうか? sub new { my $class = shift; my $self->array = []; bless($self, $class); return $self; } sub func { my $self = shift; $self->arrayに配列のデータを入れる。 }

    • ベストアンサー
    • Perl