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

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

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

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

Q&A

4回答

1873閲覧

javascriptにおけるクラスの定義について

satoudayo

総合スコア17

JavaScript

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

0グッド

0クリップ

投稿2018/04/26 14:38

編集2022/01/12 10:55

タイトルについてる初心者マークの通りプログラミング初心者なので意味不明なことを書いてるかもしれません。訳の分からないことを書いていたら訂正するので教えてください;;

本題です。Javascriptの勉強をしていて自分で調べても分からないことがあったので質問を投稿しました。クラスの定義というやつです。元々javaScriptはクラスがない言語だけど最近クラスが出来たよとか、それまではprototypeを使って書いてたよとか記事によって内容がまちまちでどうも分かりません。過去の記事を遡って勉強することも多いのでprototypeによるクラスの定義と普通のクラスの定義どちらとも覚えたいんですけど初心者向けに解説してるサイトがどうも見当たらなくて...。
クラスの意味はなんとなく分かります。クラスにはプロパティとメソットがあって、インスタンス化する時に引数を渡してプロパティの値に代入されていって、簡単にオブジェクトが出来るみたいな感じですよね。
ほんでクラスについていくつか聞きたいことがあるので質問を箇条書きしていきます。

①最近出来るようになったというprototypeを使わないクラスの定義方法を教えて欲しいです。またクラスの定義方法を見ているだけではイメージがわかないので、定義したクラスを用いて何かをするところまで教えていただけるとすごく助かります;;

②確認の為の質問です。オブジェクトというのはプロパティとメソットの集合体のことであり、クラスとはオブジェクトを作る設計図のことである。プロパティとは連想配列のようなものであり、値には番号ではなく名前がつけられている。メソットとはクラスやオブジェクトの中に書かれている関数のことである。
この解釈に間違いはないでしょうか。間違いがあれば教えて欲しいです。

③配列の書き方に種類があるように、クラスの定義方法にも種類があるのでしょうか(prototypeによる書き方は全て除く)。もし複数種類があればそれも教えて欲しいです。

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

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

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

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

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

guest

回答4

0

元々javaScriptはクラスがない言語だけど最近クラスが出来たよとか、
それまではprototypeを使って書いてたよ

これは本当です。
JavaScriptには言語仕様としてクラスはありません。
ES2015という3年前に出来た新しい規格でclass構文が実装された事で、
見てくれだけはJavaやPHP等のクラスベースの書き方が出来るようになりました。

しかし、JavaScriptは下位互換を意識する言語ですので、
内部ロジックでは昔のバージョンから変わらず、
既製品の関数をnewで分裂させていくプロトタイプベースならではの手法を使っています。

  1. 最近出来るようになったというprototypeを使わないクラスの定義方法を教えて欲しいです。

これは「ES2015 クラス」等のワードで検索してみてください。

  1. プロパティとは連想配列のようなものであり、値には番号ではなく名前がつけられている。メソットとはクラスやオブジェクトの中に書かれている関数のことである。

前半は合ってます。

恐らく意味合いとしては大丈夫だと思いますが、一応日本語的に微妙なので突っ込みます。
プロパティが連想配列なのではありません。
プロパティの集合であるオブジェクトが連想配列なのです。
なのでプロパティはキーと値のセットみたいなものだと解釈して下さいね。

メソットは外国人の名前で、メソッドの方ですね。
解釈は大まかには大丈夫ですが、関数との違いはそのクラスやオブジェクトに属するという意味合いが強い事でしょうね。

基本的に関数というのはAの値をBの値に加工して返すのが一般的です。
数学のf(x)みたいなやつですからね。
所がオブジェクトやクラスから生成したインスタンスは、具体的な値であるプロパティをいくつも持っています。

なのでその値を見せて!というメソッドを用意すれば、
同じメソッド名を実行したのに、得られる結果が変わるわけですね。

  1. クラスの定義方法にも種類があるのでしょうか

ありません。ES2015で追加されたクラスの定義方法1個だけです。

投稿2018/04/27 18:35

miyabi-sun

総合スコア21145

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

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

satoudayo

2018/04/27 21:21

どうも丁寧にありがとうございます;; 調べてみてとりあえず書いてみたんですけど、合っていますかね。おしえてほしいです;; ソロバン教室に通う子ども達を作りたいです。そろばん教室にいる子どもたちにはそれぞれ名前や性別年齢という情報があります。そして彼らは暗算が得意で礼儀正しいので挨拶をすることも出来ます。 function kodomo(name,age,seibetu){ this.name=name; this.age=age; this.seibetu=seibetu; this.aisatu=function(){ console.log("私の名前は"+this.name+"です"); } this.kakeizan=function(suuziichi,suuzini){ console.log("数字"+suuziichi+"×"+suuzini+"は"+suuziichi*suuzini+"です"); } } var seitoichi=new kodomo("たろう",10,"男"); var seitoni=new kodomo("あやこ",12,"女");
satoudayo

2018/04/27 21:27

上の方に書いてあるコンストラクタ?関数?がクラスと呼ばれる設計図。this.nameやthis.ageがプロパティで受け取った引数を代入する。ほんでkodomoクラスを元にnewを用いて作られたのがたろうくんやあやこちゃんといったインスタンスである。こんなかんじであってますか...?。?
satoudayo

2018/04/27 21:28

それからfunctionがついてたらとりあえず全部関数なんじゃないかと勝手に思っているんですけど、間違いなのでしょうか...?。?
miyabi-sun

2018/04/28 01:32

> こんなかんじであってますか...? ES5までのクラス(ぽいものと)インスタンスの作り方を前提としたら合ってますよ。 メソッドの作り方はそれだと毎回関数のオブジェクトを生成する作りなってしまい、kodomoのインスタンスを沢山(100人、1000人)生成する場合だと重くなってしまいます。 記述が同じだけど別のメモリ空間を消費するメソッドが大量に作られますからね。 一度kodomo関数のお外に出てから、 kodomo.prototype.aisatu = function ... と続けるように書き直してみてください。 まぁ、これからの時代はES2015の書き方の方が良いのでこのクラスの作り方は忘れてしまって構いません。 > functionがついてたらとりあえず全部関数なんじゃないかと勝手に思っているんですけど、間違いなのでしょうか...? functionにも色々あります。 数学の厳密な定義ではf(a) = bが保証されるものが関数ですが、JSのような言語だと命令を束ねたサブルーチンとしても扱います。 オブジェクト指向の条件というのはクラスじゃなくて、インスタンスを作れるか否かなんですよ。 なので別に元ネタはクラスという特別なものを用意しなくても、別に関数でいいじゃんって思想がJavaScriptです。 だからfunctionからインスタンスを作るのが普通の風変わりした実装なんですね。
guest

0

混乱が激しいですね。あちこちに知識が不足している箇所があるように思えます。
webで必要な部分だけで勉強しようとしてないでしょうか?

他にも誤りがありますが②の理解は誤りです。(失礼ですが、山ほどの指摘があるため割愛します。)

prototypeによるオブジェクトの定義とclassを使ったオブジェクトの定義は初心者であれば使い方も含めどちらか片方をキチンと理解すべきです。両方を一気に覚えるのは初心者向けではないと思います。そのため初心者用の説明がないのだと思われます。

体系だった入門書(webも可)などを順を追って読んでいく必要があると思われます。

③に関しては、javascriptは他の言語と比べいろいろな方法を許しています。ついでにこたえられるような分量ではありません。自由度が高いのが魅力でもありますが、この点ではあまり初心者向けではない言語かもしれません。

投稿2018/04/27 01:41

iwamoto_takaaki

総合スコア2883

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

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

satoudayo

2018/04/27 02:34 編集

function ningen(name,age,sintyou,taijuu,seibetu){ this.name=name; this.age=age; this.taijuu=taijuu; this.sintyou=sintyou; this.seibetu=seibetu; } var ningenichi= new ningen("ゆうすけ",20,170,60,"男"); var ningenni= new ningen("ひとみ",30,150,50,"女");
satoudayo

2018/04/27 02:33

functionを用いて擬似的なクラスを作って、newを用いてインスタンス化ってこんな感じであってますか...?。?
iwamoto_takaaki

2018/04/27 02:45

その書き方もありますね。あまり推奨される書き方でないかもしれませんが、javascript特有の面白い書き方です。
iwamoto_takaaki

2018/04/27 02:54

あっ、ごめんなさい。この場合、newはいりませんね。 var ningenichi= ningen("ゆうすけ",20,170,60,"男");
iwamoto_takaaki

2018/04/27 02:58

function ningen(name,age,sintyou,taijuu,seibetu){ this.name=name; this.age=age; this.taijuu=taijuu; this.sintyou=sintyou; this.seibetu=seibetu; return this; }; var ningenichi= ningen("ゆうすけ",20,170,60,"男"); var ningenni= ningen("ひとみ",30,150,50,"女");
iwamoto_takaaki

2018/04/27 02:59

"return this;"とfunctionの最後は"};"です。
satoudayo

2018/04/27 03:07

console.log(ningenichi); と書いてコンソールのぞくとウィンドウオブジェクトが出てきました;;
iwamoto_takaaki

2018/04/27 03:22

ほんとだ、私が根本的に間違ってる。 console.log(ningenichi.name) -> ひとみ thisが新しく作らていない。javasriptのthisは扱いが難しいですね。 自分で書いていたのに”ついで”で答えて失敗した。ショボ。 この件の質問をおこしたら、詳しい人が速攻回答くれると思うのであらためて質問してみてください。
Lhankor_Mhy

2018/04/27 05:36

new 演算子は this をインスタンスに束縛し、インスタンスの[[prototype]]の参照をコンストラクタのprototypeにします。 new 演算子なしでのクラス記述はできないことではないですが、かなり分かりにくいコードになると思います。
iwamoto_takaaki

2018/04/27 05:51

なるほど。 (とりあえず、new相当としててthat={};を定義してthatにプロパティを追加したらちゃんと出ました。でもこれはちょっと違う気がする・・・)
think49

2018/04/28 00:58

To: iwamoto_takaaki さん 普通に関数呼び出しした場合、this 値の初期値はStrict Modeならundefined、非Strict Modeならグローバルオブジェクト(ブラウザならwindow)が適用されます(アロー関数は少し違いますが)。 new 演算子を使う時と使わないときでthis値の挙動が変わるので、一部のビルトイン関数はnew演算子による呼び出しを強制しています。 Map(); // TypeError: Constructor Map requires 'new'
guest

0

限定した内容の範囲で、回答(とヒント)を書いておきます。

回答

➀回答なし

ただヒントとなる記事を挙げておきます こちら

#最近出来るようになったというprototypeを使わないクラスの定義方法・・・ の文を読むと
実は定義方法をご存知ではないか?と思えるからです。

オブジェクトというのはプロパティとメソットの集合体のことであり、クラスとはオブジェクトを作る設計図のことである。プロパティとは連想配列のようなものであり、値には番号ではなく名前がつけられている。メソットとはクラスやオブジェクトの中に書かれている関数のことである。

出典はどちらの本でしょうか。ネットでしたらURLを教えてください。
この種の情報は良い回答をもらうための必須条件だと思います。

言語はrubyですが一般的なクラスの解説を引用します。 こちら

「クラスとメソッド」を読んでみてください。これが正解だと思います。

➂回答なし

回答してもらうためのヒント
こちら
も読んでみてください。

投稿2018/04/26 19:04

kawakawa2018

総合スコア1195

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

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

0

js

1class wallet{ 2 constructor(name, cash){ 3 this.name = name; 4 this.cash = cash; 5 } 6 show(){ 7 return `${this.name}のお財布には${this.cash}円入っています。` 8 } 9 payment(x){ 10 this.cash -= x; 11 return x; 12 } 13 income(x){ 14 this.cash += x; 15 return x; 16 } 17} 18 19let tanakaWallet = new wallet('田中', 1000); 20let satoWallet = new wallet('佐藤', 1000); 21satoWallet.income( tanakaWallet.payment(500) ); 22alert( tanakaWallet.show() ); 23alert( satoWallet.show() );

 

違和感はありますが、「javascriptに限った範囲では」それほど間違ってはいないと思います。

js

1function wallet(name, cash){ 2 this.name = name; 3 this.cash = cash; 4} 5wallet.prototype.show = function(){ 6 return `${this.name}のお財布には${this.cash}円入っています。` 7} 8wallet.prototype.payment = function(x){ 9 this.cash -= x; 10 return x; 11} 12wallet.prototype.income = function(x){ 13 this.cash += x; 14 return x; 15} 16 17let tanakaWallet = new wallet('田中', 1000); 18let satoWallet = new wallet('佐藤', 1000); 19satoWallet.income( tanakaWallet.payment(500) ); 20alert( tanakaWallet.show() ); 21alert( satoWallet.show() );

 

「prototypeによる書き方は全て除く」を読み落としていたので、③を再回答

js

1let wallet = class{ 2 constructor(name, cash){ 3 this.name = name; 4 this.cash = cash; 5 } 6 show(){ 7 return `${this.name}のお財布には${this.cash}円入っています。` 8 } 9 payment(x){ 10 this.cash -= x; 11 return x; 12 } 13 income(x){ 14 this.cash += x; 15 return x; 16 } 17} 18 19let tanakaWallet = new wallet('田中', 1000); 20let satoWallet = new wallet('佐藤', 1000); 21satoWallet.income( tanakaWallet.payment(500) ); 22alert( tanakaWallet.show() ); 23alert( satoWallet.show() );

投稿2018/04/27 05:15

編集2018/04/27 05:20
Lhankor_Mhy

総合スコア35815

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問