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

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

新規登録して質問してみよう
ただいま回答率
85.50%
オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

4回答

3042閲覧

カプセル化した値を別メソッドで取得したい

退会済みユーザー

退会済みユーザー

総合スコア0

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

1グッド

1クリップ

投稿2018/01/02 03:20

編集2018/01/02 05:26

内容とタイトルが合致しているか、あまり自信がありません……

現在、コードは下記のようになっています。

JavaScript

1$(function(){ 2 3 methodB(); 4 methodC(); 5 6 // numを外部から見えないように保持したい 7 function methodA() { 8 var _num; 9 this.setNumber = function(num) { _num = num; } 10 this.getNumber = function() { return _num; } 11 } 12 13  // numを設定する 14 function methodB() { 15 var a = new methodA(); // ----- ① 16 a.setNumber(100); 17 } 18 19 // methodBの処理を行った後、変更されたnumの値を取得したい 20 function methodC() { 21 var a = new methodA(); // ----- ② 22 console.log(a.getNumber()); // 出力:undefined 23 } 24});

このとき、methodCの出力はundefinedとなりますが、コメントにも記述されている通り、
ここではmethodBでセットした100の値を取得したいのです。

それを実現するためには、①、②の宣言(インスタンス化?)をメソッドの外に出せば可能ではあるのですが……
「いや、それならいっそのことnumの変数外に出しちゃったほうが早いじゃん!」てなってます(´・ω・`)

かなり漠然とした質問ではありますが、どのように書けばオブジェクト指向っぽくmethodCで値を取得できますか?
ご教示のほど、よろしくお願いいたします。


追記:
迅速な回答ありがとうございます。
回答欄でもご指摘をいただきましたが、質問内容が漠然としすぎでしたので、追記します。

自身で上手く言語化できませんでしたが、言葉をお借りするなら、
「複数の関数 ( メソッド? ) で一つのオブジェクトを使いたい」という目的に近いです。

ただ、必要なメソッドを必要な分だけ、そのメソッド内でオブジェクト化したいのです。

現状のコードは、下記のようになっています。

JavaScript

1$(function(){ 2 3 var a = new methodA1(); 4 var b = new methodA2(); 5 var c = new methodA3(); 6 7 methodB(); 8 methodC(); 9 methodD(); 10 11 // numの変数を保持したり取得したりするメソッド 12 function methodA1() { 13 var _num; 14 this.setNumber = function(num) { _num = num; } 15 this.getNumber = function() { return _num; } 16 } 17 18 // fooの変数を保持したり取得したりするメソッド 19 function methodA2() { 20 var _foo; 21 this.setFoo = function(foo) { _foo= foo; } 22 this.getFoo = function() { return _foo; } 23 } 24 25 // barの変数を保持したり取得したりするメソッド 26 function methodA3() { 27 var _bar; 28 this.setBar = function(bar) { _bar = bar; } 29 this.getBar = function() { return _bar; } 30 } 31 32 // いろんな値を設定する[ここではメソッドA1、メソッドA2だけ使いたい] 33 function methodB() { 34 a.setNumber(100); 35 b.setFoo("Foo"); 36 } 37 38 // いろんな値を設定する[ここではメソッドA2、メソッドA3だけ使いたい] 39 function methodC() { 40 b.setFoo("Foo"); 41 c.setBar("Bar"); 42 } 43 44 // methodA1~A3の処理を行った後、変更されたnumの値を取得したい 45 function methodD() { 46 console.log(a.getNumber()); // 出力:100 47 console.log(b.getFoo()); // 出力:Foo 48 console.log(c.getBar()); // 出力:Bar 49 } 50});

しかし、このコードだと、methodBはメソッドA1、メソッドA2しか使わないにも関わらず、
メソッドA3も使おうと思えば使えてしまいます。
同様に、methodCもメソッドA1が使えてしまいます。

今回は、メソッドが3つの場合を挙げましたが、これが5個、10個……になってくると、
どこで何を使っているのかがかなり分かりにくくなってしまうので、
このコードの書き方は問題ありそうだなあ……と思えてきたため、質問いたしました。

それぞれのメソッドで、必要な分だけオブジェクト化して使用したいと考えています。
しかし、構造的に、どのように記述すればいいのかが分かりません(´・ω・`)

今度は、そこそこ質問の意図が明確になったような気がします……が、曖昧な箇所等あれば随時追記します。
ご教示のほど、よろしくお願いいたします。

sota_u👍を押しています

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

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

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

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

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

guest

回答4

0

ベストアンサー

もしもオブジェクトabcが関連するデータである場合、一つのオブジェクトにまとめたほうが綺麗だと思います。
例えば、

// methodA1~3が定義済みであり、データa,b,cに関連性があるものとして function hogeDataManager() { this.a = new methodA1(); this.b = new methodA2(); this.c = new methodA3(); this.initAB = function() { this.a.setNumber(100); this.b.setFoo("Foo"); }; this.initBC = function() { this.b.setFoo("Foo"); this.c.setBar("Bar"); }; this.logAllValue = function() { console.log(this.a.getNumber()); // 出力:100 console.log(this.b.getFoo()); // 出力:Foo console.log(this.c.getBar()); // 出力:Bar }; } var m = new hogeDataManager(); m.initAB(); // methodB m.initBC(); // methodC m.logAllValue(); // methodD

普通、オブジェクトにはいくつかのメンバ変数がいて、すべてのメソッドですべてのメンバ変数を使用するわけではありませんので、これでも問題はないかと思います。
ほかの場所でnewする必要があるのであれば、abcのセッターを用意すれば事足ります。

ほかにも、上記オブジェクトをabcのラッパーにしたり、オブジェクトを複数に分けず、統合してしまう(_num,_foo,_barをhogeDataManagerのメンバにしてしまう)やり方も取れます。
ラッパーは既存に少し手を加える場合によく取られる方法で、統合はオブジェクトの大きさや関連度によっては行われます。

投稿2018/01/02 07:34

編集2018/01/02 08:05
moredeep

総合スコア1507

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

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

退会済みユーザー

退会済みユーザー

2018/01/02 08:02 編集

回答ありがとうございます。 非常にコンパクトにまとめられていて、感動しました。 しかし、初歩的な質問で大変恐縮なのですが、このメソッド内部で 設定している関数の呼び出し方がよく分かりません…… 実際にlogAllValueを外部から呼び出して値を出力するためには、どうすればいいですか?
moredeep

2018/01/02 08:06

hogeDataManagerをmethodA1~3と同じように使用します。一応追記しましたので、試してみてください。
退会済みユーザー

退会済みユーザー

2018/01/02 08:24

出力できました! JavaScriptの経験が浅く、thisがまだうまく使いこなせていないので、 要勉強ですね……追加回答、本当にありがとうございました。
guest

0

おそらく、やりたいことは以下のようなことでしょうか?

javascript

1var Accessor = function(initValue) { this._value = initValue; }; 2Accessor.prototype.setValue = function(value) { this._value = value; }; 3Accessor.prototype.getValue = function() { return this._value; }; 4 5var Executor = function() { 6 this._num = new Accessor(10); 7 this._foo = new Accessor("foo"); 8 this._var = new Accessor("bar"); 9}; 10 11Executor.prototype.execA = function() { 12 this._num.setValue(100); 13 this._foo.setValue("FOO"); 14}; 15 16Executor.prototype.execB = function() { 17 this._foo.setValue("FOO"); 18 this._bar.setValue("BAR"); 19}; 20 21Executor.prototype.execC = function() { 22 console.log(this._num.getValue()); 23 console.log(this._foo.getValue()); 24 console.log(this._var.getValue()); 25}; 26 27var executor = new Executor(); 28 29executor.execA(); 30executor.execC(); 31

投稿2018/01/02 09:21

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/01/02 10:43

解決済みとした後でのコメントとなってしまい、大変申し訳ありません…… Javaのイメージが先行して、すべてのコードを理解しているわけではありませんが、 そうです!!質問した当初のイメージ的には、こんな感じで書きたかったんです…!! prototypeについて、もう少し詳しく学習した後、是非参考にさせていただきます。 回答いただき、本当にありがとうございました。
guest

0

情報をどういう生存期間として考えるかによってどのように管理するかは色々な戦略があると思います。

  1. モジュール単位の情報なのか
  2. 特定の文脈単位(関数を呼び出すと一時的にできる文脈など)なのか
  3. インスタンス単位の情報なのか

java

1// 1. 2var num; 3 4// 2. 5class Something { 6 constructor() { 7 this.num = ...; 8 } 9} 10 11// 3. 12 13function higherOrderFunction() { 14 var num; 15 16 function reference(...) { 17 return ... num ...; 18 } 19 20 function sideEffect(...) { 21 num = ...; 22 } 23 24 return [reference, sideEffect, ...]; 25}

コードからは2.か3.であろうと思えますが、オブジェクトの外部からの隠蔽(つまり2.)なのか巨大なオブジェクト実装の中のそれぞれの関数からの隠蔽なのか(つまり3.)今一つ曖昧な感じがしました。

単に文法とコード上の意味だけで論じてもかまわないと思うのですが、どのような情報をどう管理したいのか(ユースケース)の想定を明確にして論じると、より有意義な議論になるような気がします。つまり閲覧者がどこにポイントを置くかを考えやすい(回答しやすい)と思います。


追記:

追記された部分を拝見しましたが、BeatStarさんのコメントのようなアプローチで整理できる気がしました。

もしアクセスする情報ごとにメソッドのグループが単純に分類できるようならそれぞれを囲むスコープで定義するという方法もある気がします。しかしそんなにはっきりと分かれるようなら元々別のモジュールとして定義できる気がするのでそもそも解にならないのかも知れませんね・・・。それに分かり易さの点からいえば下記のv1, v2, ...のようなコンテキストをある論理的な塊のオブジェクトとしてまとめ、特にmyModule内部の関数群からそうまで厳密には区別しなくてよい気もします。そのあたりコンテキストのライフサイクルによっても適切さが変化するような気はします(下記は単純にA,Bそれぞれに静的なコンテキストだけが必要とされるケースしか表していません)

javascript

1// グループA, Bがあったとして 2 3function myModule() { 4 var a1, a2, b1, b2; 5 6 [ a1, a2 ] = (function () { 7 var v1, v2, v3, ...; // a1, a2の共通コンテキスト 8 9 function a1() { ... } 10 function a2() { ... } 11 return [a1, a2]; 12 })(); 13 14 [ b1, b2 ] = (function () { 15 var v1, v2, v3, ...; // b1, b2の共通コンテキスト 16 17 function b1() { ... } 18 function b2() { ... } 19 return [b1, b2]; 20 })(); 21 22 // a1(), a2(), b1(), b2()などを用いた論理 23 ... 24}

投稿2018/01/02 04:28

編集2018/01/02 07:06
KSwordOfHaste

総合スコア18392

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

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

KSwordOfHaste

2018/01/02 04:29

すみません。回答になってないですね・・・
退会済みユーザー

退会済みユーザー

2018/01/02 05:29

そんなことはありません。 そもそもの質問内容が悪かったので、加筆いたしました。 意図した内容が少しでも明瞭化されてれば……と思います。
guest

0

読解力が足りなくてすみません...

もしかして、複数の関数 ( メソッド? ) で一つのオブジェクトを使いたいということでしょうか?

それなら、

方法1: 呼び出し元( methodB, methodCを呼び出しているところ ) で、インスタンス化し、引数として渡す。

例:

JavaScript

1 2// function methodAは プロトタイプだとして。 3 4function methodB( obj ){ 5 obj.setNumber( 100 ); 6return obj; 7} 8 9function methodC( obj ){ 10 // 出力 11}
方法2: methodB,CそれぞれもmethodAのメンバとして定義する
方法3: 方法1に同じだが、管理クラスのようなものを設けてそれでアクセスする

例:

JavaScript

1// すでにfunction methodAはあるとして 2function methodManager(){ 3 // Javaとかでいうリスト構造を持っているとする。( var list[] ) 4 5 this.add = function( num ){ /* listに追加 */ } 6 this.getObj = function( pos ){ /* posの位置の値を返す */ } 7}

( もちろん、getObjメソッドを showメソッドとして、出力してもいいが。あくまで例。 )

投稿2018/01/02 04:15

BeatStar

総合スコア4958

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

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

退会済みユーザー

退会済みユーザー

2018/01/02 08:34

回答ありがとうございました。 此方の見識が狭く、提示いただいた手法を上手く使いこなせていませんが、 方法3の管理クラスを作成する方法は、自分なりに形を変えて採用するかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問