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

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

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

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

Q&A

解決済

2回答

4286閲覧

Javascriptの関数オブジェクト及びインスタンスにメソッドを追加したい

SugiuraY

総合スコア317

JavaScript

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

0グッド

0クリップ

投稿2017/01/26 12:58

まだまだJavascriptの初心者なのですが、オブジェクトやprototypeチェーンの考え方を学んでいく中に単純ばことがわからなくなってしまいました。。
下記の書く内容について、もしよろしければご教示ください。

(1)下記の(A)のようにFooの関数オブジェクトに新たなメソッドを追加したいと思います。ここではfunction () {document.write("hello");}が帰ってきているのでFooオブジェクトにAメソッドが追加できていると理解して良いのでしょうか?

(2)とあるサイトで既存のオブジェクトにメソッドを追加するときはprototypeに追加すべき内容を拝見しました。(ttp://www.openspc2.org/reibun/javascript/koubun/039/)
prototypeに格納することで親も子も共通して利用出来るというざっくりした認識でいるのですが、実際に(A)と(B)で何が違うのでしょうか?
例えばここでFoo.Aでメソッドを呼び出せないことが不思議です。チェーンを辿って
function() {document.write("hello");}を呼び出してくれると認識しておりました。

(3)下記の(C)のようにインスタンスにメソッドを追加するコードはこのような形でよいのでしょうか?また、また、prototypeを利用すればFooでもアクセスできるのでしょうか?

(4)下記の(D)のように、インスタンスを利用しても4という結果を取得できない理由がわからないのですが、どこに問題があるのでしょうか?

JavaScript

1(A) 2function Foo() {} 3Foo.A = function() {document.write("hello");} 4console.log(Foo.A); 5//function () {document.write("hello");} 6 7(B) 8function Foo() {} 9Foo.prototype.A = function() {document.write("hello");} 10console.log(Foo.prototype.A); 11//function () {document.write("hello");} 12 13(C) 14function Foo() {} 15Foo.A = function() {document.write("hello");} 16var foo = new Foo(); 17foo.B=function() {document.write("good-bye");} 18console.log(foo.B); 19//function () {document.write("good-bye");} 20 21(D) 22 function Foo() {} 23Foo.A = function(n) {return n+n} 24 25var foo = new Foo(2); 26console.log(foo.A); 27//function (n) {return n+n}

基礎的なことかと思うのですが、どうしても理解しようと思っており、質問させていただきました。よろしくお願い申し上げます。

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

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

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

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

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

guest

回答2

0

(1) そのとおりです。JavaScriptでは、関数もFunctionというオブジェクトです。

(2)関数オブジェクトのprototypeプロパティは、その関数オブジェクトのプロトタイプではありません。これは、関数をコンストラクタとして使った場合に、新しく作られたオブジェクトのプロトタイプとなるオブジェクトなのです。

あるオブジェクトのプロトタイプを得たい場合、Object.getPrototypeOf()を使うか、ES6で標準化された__proto__プロパティからアクセスします。なお、関数のプロトタイプオブジェクトはすべて同じ(Function.prototype)なので、そこに値を自分で追加することはあらゆる関数オブジェクトに影響してしまう、という動作の性質からプロトタイプ汚染と呼ばれ、基本的には禁じ手に近い技です。

(3)(2)で触れたように、Foo.prototype.Bを定義しておけば、インスタンスごとにメソッドをつけなくても、foo.Bとしてアクセスできます(foo.__proto__ == Foo.prototypeです)。

(4)newしても、関数オブジェクト自体にあるメソッドは引き継がれません。1つ1つ定義するか、prototypeに定義しましょう。

投稿2017/01/26 13:24

maisumakun

総合スコア145183

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

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

SugiuraY

2017/01/26 22:50

maisumakun様 ご回答有難うございます。わかり易い回答でおおむね理解ができました。(4)についてだけ確認したいのですが、関数オブジェクトのメソッドは引き継がれないというこどですが、ともすれば関数オブジェクトのインスタンスを作る意味自体がないと言う事でしょうか?また、普通のオブジェクトも同様に、プロパティはコピーされ、メソッドはコピーされないのでしょうか?
maisumakun

2017/01/26 22:54

他の言語で言えば「クラスメソッド」に当たるようなものを、関数オブジェクトに直接入れておく例があります。例えば、jQueryでは、jQuery()自体は関数ですが、jQuery.XXX()の形で呼び出せるメソッドは、Ajaxやユーティリティ関数のように、「jQueryのインスタンスとあまり関係しない」メソッド群となっています。
guest

0

ベストアンサー

オブジェクト(連想配列)を利用するパターン

基本的な方法。

javascript

1var Obj = {}; 2 3Obj.method1 = function(){...}; 4Obj.method2 = function(){...}; 5 6 7// 別パターン 8var Obj = { 9 method1: function(){...}, 10 method2: function(){...} 11} 12

プロトタイプを利用するパターン

前述の方法にはメモリ消費の面で無駄がある(複数コピーした場合にメソッドもコピーされる)ので、こちらの利用が推奨されます。

方法1

  • 1つ1つのメソッドをプロトタイプに定義する形式。
  • 新たなメソッドの追加が容易。
var Constructor = function(){ // インスタンス変数の定義 }; Constructor.prototype.method1 = function(){ // メソッドの処理 }; Constructor.prototype.method2 = function(){ // メソッドの処理 };

方法2

  • Constructor.prototype = {...} を再度定義すると、以前定義したメソッド全て失われる点に注意。

javascript

1var Constructor = function(){ 2 3} 4Constructor.prototype = { 5 method1 : function(){ 6 // メソッドの処理 7 }, 8 method2 : function(){ 9 // メソッドの処理 10 } 11} 12 13// method3を追加するつもりでこのように書いてしまうと、method1,2が失われてしまう。 14Constructor.prototype = { 15 method3 : function(){ 16 // メソッドの処理 17 } 18} 19

投稿2017/01/27 01:54

yamato_hikawa

総合スコア2092

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

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

SugiuraY

2017/01/29 02:04

ご回答いただき、ありがとうございます。とてもわかりやすかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問