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

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

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

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

Q&A

解決済

2回答

776閲覧

javascript Object()コンストラクタとObject.create()について

old_dog

総合スコア51

JavaScript

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

0グッド

0クリップ

投稿2021/08/18 08:35

編集2021/08/18 08:39

Object()コンストラクタとObject.create()で生成するオブジェクトなど、生成方法がいくつかあって混乱しています。下記11個の生成方法でつくったオブジェクトの理解が正しいのか、お時間のある方に見てもらえたらと思い投稿します。

function f(){return 11;} o1 =Object(f); // f f(){return 11} o2 =Object(f()); // Number(11) o3 =Object(new f); // f .. Prototype:Object o4 =Object(new f()); // f .. Prototype:Object o5 =new Object(f); // f f(){return 11} o6 =new Object(f()); // Number(11) o7 =new Object(new f); // f .. Prototype:Object o8 =new Object(new f()); // f .. Prototype:Object o9 =Object.create(f); // Function .Prototype:f f(){return 11} // o10=Object.create(f()); // Uncaught TypeError:... o11=Object.create(new f); // f .. Prototype:f o12=Object.create(new f()); // f .. Prototyoe:f // 返値 11 を表示 console.log(o1()); // o5 console.log(Number(o2)); // o6 console.log(Object.getPrototypeOf(o3).constructor()); // o4 o7 o8 console.log(Object.getPrototypeOf(o9)()); console.log(Object.getPrototypeOf(o11).constructor()); // o12

上記を見ていると、

  1. Object()コンストラクターでは、Object() と new Object()は、同じ働きをしている

  どちらを使っても問題はない
2. o1とo5は、変数fに格納されているオブジェクトが戻され
3. o2とo6は、関数fの返り値のラッパー型が戻され
4. o3,o4,o7,o8は、PrototypeにObjectが設定されたfのオブジェクトが戻され
2~4はPrototypeにObjectが設定されたオブジェクトが戻る

  1. o9はf()をPrototyoeに設定した関数型が戻され
  2. o11とo12は、Prototypeにfのインスタンスが設定されたオブジェクトが戻されている

という理解でいいのでしょうか?

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

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

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

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

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

guest

回答2

0

Object()

Object()Object型に変換する関数です。
引数が「Undefined 型」「Null 型」の場合に特別なオブジェクトを返しますが、それ以外の型にはObject型への変換処理として扱います。

ToObject

Object型への変換処理は次の工程で行われます。

  • 対象が「Undefined 型」「Null 型」なら、TypeErrir
  • 対象が「Object 型」なら、対象をそのまま返す
  • 対象が「上記以外の型」なら型ごとの個別処理で「Object 型」に変換して返す

JavaScript

1'use strict'; 2function f(){return 11;} 3 4const o1 = Object(f); 5console.info(1, o1); 6console.log(o1 === f); // true 7 8const o2 = Object(f()); 9console.info(2, o2); 10console.log(Object.getPrototypeOf(o2) === Number.prototype); // true 11 12const o3 = new f(); 13console.info(3, o3); 14console.log(Object.getPrototypeOf(o3) === f.prototype); // true 15 16const o41 = new f(); 17const o42 = Object(o41); 18console.info(4, o41, o42); 19console.log(o41 === o42); // true 20console.log(Object.getPrototypeOf(o41) === f.prototype); // true 21console.log(Object.getPrototypeOf(o42) === f.prototype); // true

Object.create()

Object.create() は「第一引数を [[Prototype]] に持つオブジェクトを生成する関数」です。

JavaScript

1'use strict'; 2function f(){ return 11; } 3 4const f1 = new f; 5console.log(Object.getPrototypeOf(Object.create(f1)) === f1); // true

new Object()

ES2021で new Object() を探しましたが、現在の挙動を表す説明は見つかりませんでした。


new Object() が「[[Prototype]] に Object.prototype を持たないオブジェクト」を返す場合がある点には注意が必要です。

下記コードは多くの人が納得する挙動をしていますが、

JavaScript

1console.log(Object.getPrototypeOf(new Object) === Object.prototype); // true

下記コードの挙動には納得しない人もいると思います。

'use strict'; function f(){ return 11; } console.log(Object.getPrototypeOf(new Object(f)) === Object.prototype); // false

Re: old_dog さん

投稿2021/08/19 03:01

think49

総合スコア18189

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

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

old_dog

2021/08/20 06:08

think49様、まとめて頂いたコードと、リンク先の参照先を、何度か見返してみました。ご教授くださいましたコードは、どれも大変に整理しやすく、理解の助けになり、本当に助かりました、というか、ありがたく感じております。リンク先の解説も、見たことがないものがあり、理解が進みました。まだ理解しきれていないところもあるかもしれませんが、随分と頭が整理できてきた気がしております。 ご指導のご投稿から返事が遅れてしまって大変にすみませんでした。とてもとても学習の助けになりました。このような質問に、貴重なお時間、詳細丁寧なご解説をいただきまして、心よりお礼申し上げます。ありがとうございました。
guest

0

ベストアンサー

javascript

1function f(){return 11;}

そもそも論として、「this以外の値をreturnする」関数をnewの対象として使うこと自体が妥当ではありません。試験目的以外で書くべきではありません。

値をreturnする関数をnewで呼んだ場合、

  • 返り値がオブジェクトだった場合→新規作成されたオブジェクトは捨てられnewの返り値は関数の返り値となる
  • 返り値がオブジェクトでない場合→返り値は無視され、新規作成されたオブジェクトが返される

という、値ごとに正反対な挙動を示すようになります(MDN)。

投稿2021/08/18 08:47

maisumakun

総合スコア146018

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

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

maisumakun

2021/08/18 08:58 編集

資格試験や言語処理系自体の実装などのように、エッジケースまで厳密に詰めないといけないような状況ならともかく、実用的なコードを書くという目的で検討するのなら、このコードの難解さは人工的・衒学的すぎて役に立たないと考えます。 「自分で作った関数自体をプロトタイプとしてObject.createで別なオブジェクトを作る(o9)」なんて、考えたこともなかったですし、それがなにか有意義な利用ができるかというのも疑わしいです。
old_dog

2021/08/19 02:16 編集

「this以外の値をreturnする関数をnewの対象として使うこと自体が妥当ではありません」 ご指摘をありがとうございました。このようなご指導を頂けると、大変にありがたいです。ご指摘されて初めて、インスタンススコープというものを、もっと考えるべきことを教わったような気がします。 ご指導頂きました内容は、ノートに転写して何度も読み返させていただきます。 MDNのObject.create()とObject()コンストラクターをもう数度ほど読み直します。 maisumakun様、いつも本当にありがとうございます。 いつも感謝しております。 他の方の参考にならない質問にも真摯にご指導くださいましてありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問