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

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

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

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

Q&A

解決済

2回答

1347閲覧

コンストラクター、thisに関して分からないことがあります

newyee

総合スコア213

JavaScript

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

0グッド

0クリップ

投稿2018/09/09 09:05

編集2018/09/12 06:17

javascriptを勉強している際なのですが、以下のコードに関して分からない部分が出てきてしまったため、教えて頂きたいです。

javascript

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="utf-8"> 5 6</head> 7<body> 8<script> 9 10 var Animal = function() {}; 11 12 Animal.prototype = { 13 walk : function() { 14 console.log('トコトコ...'); 15 } 16 }; 17 18 var Dog = function() { 19 20 Animal.call(this); 21 }; 22 23 console.log(this); 24 25 Dog.prototype = new Animal(); 26 27 Dog.prototype.bark = function(){ 28 29 console.log('ワンワン'); 30 } 31 32 var d = new Dog(); 33 d.walk(); 34 d.bark(); 35 36 37 38</script> 39</body> 40 41</html>

教えて頂きたい部分というのは「Animal.call(this);」この部分に関してなのですが、2点お聞きしたいことがございます。
まず、「Animal.call(this);」ここの説明として、「Animalコンストラクターを現在のthisで呼び出しなさい、という意味である。」とあったのですが、現在のthisで呼び出すとは、Animalオブジェクトにプロパティやメソッドが設定されていた場合、グローバルオブジェクトとして呼びだす、といった意味なのでしょうか?
もう一点なのですが、「ここではコンストラクターは空なのでなくても問題はないが、基底クラスでプロパティの定義など、なにかしらの初期化処理を行っている場合には、まず基底クラスのコンストラクターを処理した後、派生クラス独自の初期化処理を記述してください。」との説明があるのですが、クラスを継承する際は、基底クラスのコンストラクターを派生クラス先で処理しなければならない理由は何故なのでしょうか?
多少混乱してしまっている部分があり、うまく説明できていなかったらすみません。
ご解説頂けましたら幸いです。よろしくお願いします。

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

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

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

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

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

m.ts10806

2018/09/10 00:42

タイトルには要件を書いてください。もう少し質問内容に寄った具体的なタイトルの方が質問一覧を見たときに分かりやすくなります。
newyee

2018/09/10 02:15

ご指摘ありがとうございます。毎回質問させていただく際にどのようなタイトルにするかで迷ってしまいまして...結果大雑把なタイトルにしてしまうんですよね...
m.ts10806

2018/09/10 02:18

質問を書ききってしまってからタイトルを考えると良いのではないでしょうか。タイトルを考えてから書くと、標題決めてから作文書くときのように自由に中身が書けないことがあって余計に分かりにくくなることも多々あります。
m.ts10806

2018/09/10 02:19

「タグにあるものはタイトルに含まない」「質問内のキーワードを広い集めて組み立てる」といったやり方もあります。
newyee

2018/09/10 02:32

ありがとうございます。教えて下さった、「質問内のキーワードをひろい集めて組み立てる」こちらを意識しながら、タイトルを考えていきたいと思います。質問を書ききってしまってからの方がタイトル決めた方が良いですよね。教えて頂いた通り試してみたいと思います!
guest

回答2

0

ベストアンサー

Animal.call(this); の意味について

js

1var Dog = function() { 2 Animal.call(this); 3};

functionの中で実行されていますね。
functionの中というのはthisが指すものが呼び出され方によって変わります。

コードを見るとvar d = new Dog();と、newをつけてインスタンスを生成していますので、こうやって実行されたDogの中では、thisは生成されたDogのインスタンスを指します。
変数dに格納されるものと同一だということです。
で、callは第一引数で指定したオブジェクトを、呼び出した関数内でthisとして扱えという意味になっています。
つまり、var d = new Dog();こうやって実行されたときにはAnimalという関数の中で指すthisも、Dogのインスタンスです。
なので、変数dに格納されたインスタンスの中でのthisはすべてインスタンス自身を指すということになります。

基底クラスのコンストラクターについて

試しにこんな変更をしてみてください。

js

1var Animal = function(name) { 2 this.name = name; 3}; 4 5// 中略 6 7var Dog = function() { 8 // Animal.call(this); 消す 9}; 10 11// 中略 12 13Dog.prototype.bark = function(){ 14 console.log('%s「ワンワン」', this.name); 15}

Animalが受け取るはずのnameはどこから来るでしょうか?

誰も渡してくれないので、barkメソッドでthis.nameを参照しようとするとundefinedです。
コンソールにはundefined「ワンワン」と出てくると思います。

そこでこう修正してみてください。

js

1var Dog = function(name) { 2 Animal.call(this, name); 3}; 4 5// 中略 6 7var d = new Dog('ジョン');

こう修正すれば、ジョン「ワンワン」と出てくると思います。
Animalのコンストラクタに引数を引き継いで設定したからです。

また、こうやって変更してみたコードを見てみると、Animalのコンストラクタでthis.nameを設定したのに、Dogが持っているメソッドの中でthis.nameを参照できていますね。
これは、ひとつめで説明したようにthisを渡して同じインスタンスを指すようにしてあるからです。

こんな感じで理解できましたか?
もう少し複雑な構成で組み立てていくと、thisを渡したり継承元のコンストラクタを処理したりしなければならない意味がわかってくると思います。

試しに、Animalを継承したCatを作ってみたり、Animalのメソッドをもう少し増やしてみたりいろいろ拡張して遊んでみてください。
んでいろんな場所にログを仕込んでみてください。
聞くよりいろんなことを試してみた方が勉強になると思います。

投稿2018/09/09 10:26

spookybird

総合スコア1803

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

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

newyee

2018/09/12 07:02

ご返信遅れてしまい、すみません。 ご回答下さった部分で、勉強不足がゆえ理解できず、新しく質問などを立てさせて頂き、調べておりました。 かなり基礎的な部分が抜けており、まだまだ勉強に励まなければと痛感致しました... ご回答頂きましたおかげで、だいぶ「this」に関する理解が出来てきました。 Catオブジェクトなどを作成し、色々試してみた結果、意外にも予想通りにいったので、やはり色々と試してみなければ分からないと、勉強になりました。 すみません。何度も申し訳ないのですが、最後に、細かい部分なのですが、ご回答下さったコードの、「console.log('%s「ワンワン」', this.name);」ここの、「%s」とはどういう意味なのでしょうか? console出力しましたら、「this.name」の部分が前に来て、ジョン「ワンワン」となっていたので、何か関連があるのかなと思ったもので。調べてみたのですが、いまいちキーワードとヒットしなかったもので、聞かせて頂きました。
opyon

2018/09/12 07:19

%sが変数として機能します。カンマ「,」で区切った後に変数を指定します。 この例ですとthis.name=”ジョン”が入ります。 最終的に%s=”ジョン” + "「ワンワン」"となります。 変数は複数指定可能です。 console.log('%s%s', "A","B");とすれば、ABと出力されます。 %sの文字列以外にも%dの数値など色々な書式があります。 console.logで検索してみてください。
newyee

2018/09/12 07:32

お二方ともありがとうございました! 調べてみます!
guest

0

本題ではありませんが、いまのブラウザではclassとして、継承構造をラッピングすることもできるようになっています(IE11など古いブラウザで動かす場合にはbabelなどで変換が必要です)。

javascript

1class Animal{ 2 constructor(name){ 3 this.name = name; 4 } 5 6 walk() { 7 console.log('トコトコ...'); 8 } 9} 10 11class Dog extends Animal{ 12 bark(){ 13 console.log('ワンワン'); 14 } 15}

この場合、Dogの側にコンストラクタがないように見えますが、同じ引数を親に渡すコンストラクタがあるものとして扱われます。

投稿2018/09/10 00:18

maisumakun

総合スコア145183

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問