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

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

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

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

Q&A

解決済

2回答

2774閲覧

【javascript】コンストラクタとprototypeの定義をまとめて行いたい

t-book

総合スコア29

JavaScript

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

0グッド

1クリップ

投稿2015/04/29 16:28

いつもお世話になっています。

以下のようにコンストラクタを定義して、そのprototypeにメソッドを作成するということはよくあると思います。

lang

1function Person(name) { 2 this.name = name; 3} 4Person.prototype = { 5 log: function() { 6 console.log(this.name); 7 } 8};

このような場合に、Personを定義した箇所でまとめてprototypeも設定するやり方はありますでしょうか。

lang

1/* 定義のイメージ */ 2function Person(name) { 3 this.name = name; 4 this.prototype = { /* これだとprototypeという名前の普通のプロパティになってしまうかと... */ 5 log: function() { 6 console.log(this.name); 7 } 8 }; 9}

どうぞよろしくお願いします。

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

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

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

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

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

guest

回答2

0

プロトタイプは、コンストラクタとなる関数の実行前に設定しないと意味がないので、その関数の内側に書くことはできません。

投稿2015/04/30 00:34

maisumakun

総合スコア145184

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

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

t-book

2015/04/30 11:25

なるほど同時に設定することはできないのですね。 勉強になりました!回答ありがとうございます。
guest

0

ベストアンサー

maisumakunさんも書かれている通り、関数の内側でプロトタイプをセットすることは出来ません。
「ある」か「ない」かで言ったらないのです。

ですがプロトタイプを設定する関数を作ることで一応まとまった書き方をすることもできます。
(求めていたものとは違うかもしれませんが……)

lang

1// 第一引数に渡された関数のprototypeに第二引数に渡されたobjectをマージする関数 2function setPrototype (fn, proto) { 3 if ("object" == typeof proto) { 4 var prototype = fn.prototype; 5 var keys = Object.keys(proto); 6 for (var i = 0, j = keys.length ; i < j ; i++) { 7 prototype[keys[i]] = proto[keys[i]]; 8 } 9 } 10 return fn; // 渡された関数を返す 11}

上のような関数をを定義してから

lang

1var Person = setPrototype(function (name) { 2 this.name = name; 3}, { 4 log: function () { 5 console.log(this.name); 6 } 7});

とすればほぼ同じ物ができます。

「ほぼ」と言ったのは、

  1. Personという名前付き関数を定義するのではなく変数Personに無名関数を代入している点
  2. prototypeをオブジェクトで上書き代入するのではなく元々関数にあるprototypeにプロパティとして追加している点

が違うためです。

1)は通常は問題にならないと思います (もしこれが問題になる場面があれば教えて欲しいです)

2)についてはprototypeにオブジェクトを代入するといくつか問題がある(参考サイト)ので、こちらの方がいいかと思います。

ただ、あまり変わった書き方をするのはあまりおすすめしません。
一応こういったこともできる、というだけです。

prototypeにオブジェクトを直接代入する際に起こる問題の対応も、

lang

1function Person(name) { 2 this.name = name; 3} 4Person.prototype.log = function() { 5 console.log(this.name); 6};

普通にこうするか、
merge関数作ってやるぐらいにした方ががいいかと思います

lang

1// 第一引数に渡されたobjectに第二引数以降のobjectをマージする関数 2function merge (obj1, obj2/*, obj3, objN...*/) { 3 if ("object" == typeof obj1) { 4 for (var i = 1, j = arguments.length ; i < j ; i++) { 5 obj2 = arguments[i]; 6 if ("object" != typeof obj2) continue; 7 var keys = Object.keys(obj2); 8 for (var m = 0, n = keys.length ; m < n ; m++) { 9 obj1[keys[m]] = obj2[keys[m]]; 10 } 11 } 12 } 13 return obj1; 14} 15 16function Person (name) { 17 this.name = name; 18} 19merge(Person.prototype, { 20 log: function () { 21 console.log(this.name); 22 } 23});

長々と失礼しました。

投稿2015/04/30 10:06

MAGP

総合スコア153

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

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

t-book

2015/04/30 12:11

ご回答ありがとうございます! 今回の質問意図としましては、プロトタイプごとまとめて一つのブロック内で設定できれば、見た目上分かりやすく(エディタでも折りたためる)なるかな、と思ったためでした。 プロトタイプを設定する関数というのは思いつきませんでした。 というより質問とは趣旨が違ってくるのですが、↓ってデメリットの可能性があったのですね... Person.prototype = { log : function() {}, log2: function() {} }; // 今まで↓と単に記述の仕方が違うだけで、同じようものだと勝手に思っていました... Person.prototype.log = function() {}; Person.prototype.log2 = function() {}; たくさん書いていただき大変参考になりました。 もっと精進します。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問