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

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

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

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

Q&A

解決済

2回答

2182閲覧

JavaScriptのprototypeがよくわからなくなった

murabito

総合スコア108

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

1グッド

2クリップ

投稿2018/04/09 03:44

編集2018/04/09 05:31

★ 質問

JavaScriptのプロトタイプチェーンについてはなんとなく理解しているつもりだったのですが、復習がてらに簡単なコードを書いてログを確認したら、Chromeのコンソールで出力される結果と、node環境で出力される結果が異なり、何が正しいのか混乱してしまいました。

以下に載せている最後の行でObject.getPrototypeOf(child)のログを出力しているのですが、childのprototypeはParentなのでしょうか?それとも、Childなのでしょうか?(質問1)

また、Object.getPrototypeOf(child)typeofで確認するとobjectと出るので、Constructor Functionではないのですよね?(質問2)

★ 書いたコード

JavaScript

1//test.js 2 3'use strict'; 4 5class Parent { 6 constructor(name) { 7 this.name = name; 8 } 9 greet1() { 10 console.log('Hi, My name is ' + this.name + '.'); 11 } 12} 13 14class Child extends Parent { 15 constructor(name, age) { 16 super(name); 17 this.age = age; 18 } 19 greet2() { 20 console.log('Hi, My name is ' + this.name + '.'); 21 console.log('I am ' + this.age + ' years old.'); 22 } 23} 24 25const child = new Child('taro', 10); 26console.log(Object.getPrototypeOf(child)); 27

★ 最後の行のログ

Node

$ node test.js > Child {} //最後の行のログ出力結果

Chrome

イメージ説明

★ 解決後の補足

以下の場合、どちらも出力結果はChromeコンソール上で{constructor: ƒ}となりました。

'use strict'; class Child1 { constructor(x){ this.x = x; } } const child1 = new Child1(5); console.log(Object.getPrototypeOf(child1)); class Child2 extends function(){} { constructor(x){ super(); this.x = x; } } const child2 = new Child2(5); console.log(Object.getPrototypeOf(child2));
m.ts10806👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

NOTE:
ややこしいので,間違いが有ったらごめんなさい.


以下に載せている最後の行でObject.getPrototypeOf(child)のログを出力しているのですが、childのprototypeはParentなのでしょうか?それとも、Childなのでしょうか?(質問1)

Child.prototypeです.

また、Object.getPrototypeOf(child)をtypeofで確認するとobjectと出るので、Constructor Functionではないのですよね?(質問2)

はい. 得られるのはプロトタイプオブジェクトです. そのオブジェクトを生成したコンストラクタがある場合は, constructorプロパティから取得できます.


あるコンストラクタとそのコンストラクタから生成されたオブジェクトとの間の関係性を表すプロパティには__proto__,prototype,constructorの3つがあります.

  • obj.__proto__...このオブジェクトに対するプロトタイプオブジェクトを取得する
  • Class.prototype...コンストラクタ実行時にプロトタイプオブジェクトとするオブジェクト
  • obj.constructor...このオブジェクトを生成したコンストラクタ(クラス)

例えば次のようなコードが有った場合ログに出力される結果は全てtrueとなります.

JavaScript

1{ 2 class Base{ 3 f(){return "base";} 4 } 5 class Extended extends Base{} 6 7 const e = new Extended(); 8 console.log(e.constructor === Extended); 9 console.log(e.__proto__ === Extended.prototype); 10 console.log(Extended.prototype.constructor === Extended); 11 console.log(e.__proto__.__proto__.constructor === Base); 12 console.log(e.__proto__.__proto__ === Base.prototype); 13 console.log(e.f());//継承できていることの確認 14}

このコードをレガシーな継承で表すと次のようになります.

JavaScript

1{ 2 function Base(){} 3 Base.prototype.f = function(){return "base";} 4 function Extended(){} 5 Extended.prototype = new Base(); 6 Extended.prototype.constructor = Extended; 7 8 const e = new Extended(); 9 console.log(e.constructor === Extended); 10 console.log(e.__proto__ === Extended.prototype); 11 console.log(Extended.prototype.constructor === Extended); 12 console.log(e.__proto__.__proto__.constructor === Base); 13 console.log(e.__proto__.__proto__ === Base.prototype); 14 console.log(e.f());//継承できていることの確認 15}

投稿2018/04/09 04:24

defghi1977

総合スコア4756

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

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

murabito

2018/04/09 05:28

ありがとうございます。確かに冷静に考えればchild.__proto__はChild.prototypeでした。 ChromeのコンソールがそれをParent {}と出したり、node環境ではChildと出したりで混乱しましたが、おかげさまでクリアになりました。ChromeコンソールのParent {}のような表示はParentクラスのインスタンスであると読み替えてみれば良さそうですね。
guest

0

childのprototypeはParentなのでしょうか?それとも、Childなのでしょうか?(質問1)

childにprototypeはありません。__proto__=内部プロパティ[[Prototype]]はあります。

Object.getPrototypeOf() メソッドは指定したオブジェクトのプロトタイプ (要するに内部プロパティ[[Prototype]] の値)を返します。

Object.getPrototypeOf() - JavaScript | MDN

Object.getPrototypeOf(child)をtypeofで確認するとobjectと出るので、Constructor Functionではないのですよね?(質問2)

はい、これは、Child.prototypeです。
Childclass構文で定義されると、Child.prototypeが生成されます。その後、new演算子によりインスタンスが生成されると、child.__proto__Child.prototypeと同じ参照を持ちます。


たぶん。

投稿2018/04/09 05:00

Lhankor_Mhy

総合スコア36074

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

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

murabito

2018/04/09 05:24

ありがとうございます。参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問