javascriptを勉強している際なのですが、以下のコードに関して分からない部分が出てきてしまったため、教えて頂きたいです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
</head>
<body>
<script>
var Animal = function() {};
Animal.prototype = {
walk : function() {
console.log('トコトコ...');
}
};
var Dog = function() {
Animal.call(this);
};
console.log(this);
Dog.prototype = new Animal();
Dog.prototype.bark = function(){
console.log('ワンワン');
}
var d = new Dog();
d.walk();
d.bark();
</script>
</body>
</html>
教えて頂きたい部分というのは「Animal.call(this);」この部分に関してなのですが、2点お聞きしたいことがございます。
まず、「Animal.call(this);」ここの説明として、「Animalコンストラクターを現在のthisで呼び出しなさい、という意味である。」とあったのですが、現在のthisで呼び出すとは、Animalオブジェクトにプロパティやメソッドが設定されていた場合、グローバルオブジェクトとして呼びだす、といった意味なのでしょうか?
もう一点なのですが、「ここではコンストラクターは空なのでなくても問題はないが、基底クラスでプロパティの定義など、なにかしらの初期化処理を行っている場合には、まず基底クラスのコンストラクターを処理した後、派生クラス独自の初期化処理を記述してください。」との説明があるのですが、クラスを継承する際は、基底クラスのコンストラクターを派生クラス先で処理しなければならない理由は何故なのでしょうか?
多少混乱してしまっている部分があり、うまく説明できていなかったらすみません。
ご解説頂けましたら幸いです。よろしくお願いします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+2
Animal.call(this); の意味について
var Dog = function() {
Animal.call(this);
};
function
の中で実行されていますね。
function
の中というのはthis
が指すものが呼び出され方によって変わります。
コードを見るとvar d = new Dog();
と、new
をつけてインスタンスを生成していますので、こうやって実行されたDog
の中では、this
は生成されたDog
のインスタンスを指します。
変数d
に格納されるものと同一だということです。
で、callは第一引数で指定したオブジェクトを、呼び出した関数内でthis
として扱えという意味になっています。
つまり、var d = new Dog();
こうやって実行されたときにはAnimal
という関数の中で指すthis
も、Dog
のインスタンスです。
なので、変数d
に格納されたインスタンスの中でのthis
はすべてインスタンス自身を指すということになります。
基底クラスのコンストラクターについて
試しにこんな変更をしてみてください。
var Animal = function(name) {
this.name = name;
};
// 中略
var Dog = function() {
// Animal.call(this); 消す
};
// 中略
Dog.prototype.bark = function(){
console.log('%s「ワンワン」', this.name);
}
Animal
が受け取るはずのname
はどこから来るでしょうか?
誰も渡してくれないので、bark
メソッドでthis.name
を参照しようとするとundefined
です。
コンソールにはundefined「ワンワン」
と出てくると思います。
そこでこう修正してみてください。
var Dog = function(name) {
Animal.call(this, name);
};
// 中略
var d = new Dog('ジョン');
こう修正すれば、ジョン「ワンワン」
と出てくると思います。
Animalのコンストラクタに引数を引き継いで設定したからです。
また、こうやって変更してみたコードを見てみると、Animal
のコンストラクタでthis.name
を設定したのに、Dog
が持っているメソッドの中でthis.name
を参照できていますね。
これは、ひとつめで説明したようにthis
を渡して同じインスタンスを指すようにしてあるからです。
こんな感じで理解できましたか?
もう少し複雑な構成で組み立てていくと、this
を渡したり継承元のコンストラクタを処理したりしなければならない意味がわかってくると思います。
試しに、Animal
を継承したCat
を作ってみたり、Animal
のメソッドをもう少し増やしてみたりいろいろ拡張して遊んでみてください。
んでいろんな場所にログを仕込んでみてください。
聞くよりいろんなことを試してみた方が勉強になると思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
本題ではありませんが、いまのブラウザではclass
として、継承構造をラッピングすることもできるようになっています(IE11など古いブラウザで動かす場合にはbabel
などで変換が必要です)。
class Animal{
constructor(name){
this.name = name;
}
walk() {
console.log('トコトコ...');
}
}
class Dog extends Animal{
bark(){
console.log('ワンワン');
}
}
この場合、Dog
の側にコンストラクタがないように見えますが、同じ引数を親に渡すコンストラクタがあるものとして扱われます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
m.ts10806
2018/09/10 09:42
タイトルには要件を書いてください。もう少し質問内容に寄った具体的なタイトルの方が質問一覧を見たときに分かりやすくなります。
newyee
2018/09/10 11:15
ご指摘ありがとうございます。毎回質問させていただく際にどのようなタイトルにするかで迷ってしまいまして...結果大雑把なタイトルにしてしまうんですよね...
m.ts10806
2018/09/10 11:18
質問を書ききってしまってからタイトルを考えると良いのではないでしょうか。タイトルを考えてから書くと、標題決めてから作文書くときのように自由に中身が書けないことがあって余計に分かりにくくなることも多々あります。
m.ts10806
2018/09/10 11:19
「タグにあるものはタイトルに含まない」「質問内のキーワードを広い集めて組み立てる」といったやり方もあります。
newyee
2018/09/10 11:32
ありがとうございます。教えて下さった、「質問内のキーワードをひろい集めて組み立てる」こちらを意識しながら、タイトルを考えていきたいと思います。質問を書ききってしまってからの方がタイトル決めた方が良いですよね。教えて頂いた通り試してみたいと思います!