アプリ版:「スタンプのみでお礼する」機能のリリースについて

お世話になります。
JavaScriptを用いて、ある条件の下でArrayオブジェクトのような独自オブジェクトを定義したいのですが、ゆっくり調べている時間がなく、こちらの方を頼らせていただくことにしました。

【やりたいこと】
Arrayオブジェクトのような独自オブジェクトを定義したい。

【やりたいことの条件】
条件1:
Arrayオブジェクトが戻り値として返ってくる既存の関数があり、その戻り値であるArrayオブジェクト自身を新たなオブジェクトとして定義したい。
この関数は、
・Arrayオブジェクトの要素とは全く無関係の引数をとる。
・この関数の仕様を変更することはできない。
という特徴があります。

条件2:
独自オブジェクトを作る際の引数は、上述の既存の関数の引数と同じ。


【サンプル】
上記の説明では、少々わかりにくいかもしれませんので、使い方のサンプルを以下に示します。

既存の関数:
function immovableFunc(param1, param2) {
var myArray = new Array;

return myArray;
}

今回作りたいオブジェクト:
PseudoArray

今回作りたいオブジェクトの使われ方:
var pa = new PseudoArray(param1, param2);

そもそも、このようなオブジェクトが作れるのか?、作れるとするならばどのように記述するのか?見当も付かない状態です。
皆さんのお知恵を拝借させていただければと思います。
どうぞ、よろしくお願いいたします。

A 回答 (4件)

> メソッドやプロパティは独自のものを使いますので、Arrayオブジェクトのメソッドやプロパティは継承しなくてもかまいません。



ということであれば、以下でどうでしょう?
-----------------------------------------------------
<html>
<head>
<title></title>
<script>
var PseudoArray = function (param1, param2) {
this.prop1 = param1;
this.prop2 = param2;
var ary = ["a", "b", "c"];
for(var i = 0; i < ary.length; i++){
this[i] = ary[i];
}
};

PseudoArray.prototype = {
prop1 : null,
prop2 : null,
method1 : function(a, b){
return (a + b + this.prop1);
},
method2 : function(a, b){
return (a + b + this.prop2);
}
};
var pa = new PseudoArray(1, 2);
var hoge1 = pa.method1(3, 4);
var hoge2 = pa.method2(5, 6);
var str = hoge1 + ", " + hoge2 + ", " + pa[2];

</script>
</head>
<body onload="document.getElementById('test').innerHTML = str;">
<div id="test"></div>
</body>
</html>
------------------------------------------------
書き方はちょっと違いますが、仕組みはNo2で挙げた参考URLと一緒です。
自オブジェクトのメソッド・プロパティはthis経由で使えます。
参考になりますでしょうか。
    • good
    • 0
この回答へのお礼

susie-t様、再度のご回答ありがとうございます。

うまく動きました!
ご回答いただいたコードを参考に、こちらの状況に合わせて下記のように書いてみました。

-----------------------------------
// テスト用スタブ
// param1, param2 は無視されていますが、
// 実際は、配列の要素を決定するために使われます。
function immovableFunc(param1, param2) {
var a = new Array;
a[0] = 1;
a[1] = "msg";
a[2] = false;
return a;
}

function PAMethod1() {

}

function PAMethod2() {

}



var PseudoArray = function(param1, param2) {
var ary = immovableFunc(param1, param2);
for ( var i=0; i<ary.length; i++ ) {
this[i] = ary[i];
}
this.prop1 = ary.length;

}

PseudoArray.prototype = {
prop1 : null,
…,
method1 : PAMethod1,
method2 : PAMethod2,

}
-----------------------------------

先のご回答で
「どうしてもやるとすればArrayクラスのメソッド・プロパティを個別に指定してコピーすることになりますが・・・。」
と書かれたことだったのですね。
具体的にコードを書いてくださって、大変参考になりました。

本当にありがとうございました。

おかげさまをもちまして本件は解決したのですが、もうしばらく、質問を締め切らずに皆様のご助言を賜りたいと思いますので、ご了承願います。

お礼日時:2007/11/02 17:19

> (C++でしたら、不自由せずに使える程度です)、


C++のTemplateはJavaScriptでは使えないと思いますが、
JAVA/C++のClass(JavaScriptではコンストラクター)定義+インスタンス生成の書き方もできます。
この方法なら、プライベート変数・関数とパブリック変数・関数の使い分けもできます。

function PseudoArray(param1, param2){
//public
 this.prop1=param1||0;
 this.prop2=param2||0;
 this.method1=function(){
  return prop1;
 };
 this.method2=function(){
  return calc();
 };

//private
 var a=5;
 function calc(){
  return this.prop2+a;
 }
}

var pa = new PseudoArray(1, 2);
var a=pa.calc(); // calc not defined;
var a=pa.method2(); //a=7

---------------
> var PseudoArray = function(param1, param2) {
> var ary = immovableFunc(param1, param2);
> for ( var i=0; i<ary.length; i++ ) {
> this[i] = ary[i];
> }
> this.prop1 = ary.length;
> …
> }

aryの使い道がよくわかりませんが、
値をコピーせずに、ary自体をプライベート変数として保持しておき、値の一元管理をした方が良い様な気がします。

function PseudoArray(param1, param2) {
 var ary = immovableFunc(param1, param2);
 this.prop1 = ary.length;
 …
 this.getAry=function(id){
  return ary[id];
 };
 this.getLength=function(){
  return ary.length; //prop1の代わり
 };
}
var pa=new PseudoArray(1, 2);
var hoge1=pa.getAry(1);
alert(hoge1) // "msg"

または、
this.ary=immovableFunc(param1,param2);として、pa.ary[1]で参照するかですかね。


*全角スペースでインデントしています。
*this.prop1=param1||0;
 param1が指定されない場合の初期値を0にする方法です(指定がなければundefined)。
*JavaScript"らしい"書き方はprototypeだと思います。
*動作未検証です。

この回答への補足

この場をお借りしまして、質問締め切りの連絡をさせていただきます。

taloo様、susie-t様、この度はいろいろとありがとうございました。
お二方から頂きましたご回答を参考に、JavaScript の習得にはげみたいと思います。

なお、その後の調査(思いつきによる試行?も含めて)により、下記のコードでも動きましたことをご報告申し上げます。

------------------------------
function object(o) {
function F() {}
F.prototype = o;
return new F();
}

function PseudoArray(param1, param2) {
var ary = immovableFunc(param1, param2);
var pa = object(ary);
pa.prop1 = ary.length;

pa.method1 = PAMethod1;
pa.method2 = PAMethod2;


function PAMethod1(param3, param4) {
return ret;
}

function PAMethod2(param5, param6) {
return ret;
}


return pa;
}
------------------------------

どうやら、Array オブジェクトの継承ができてるようです(独自メソッドの定義内で、this.slice, this.shift などのメソッドが使えることを確認しました。)。
ただ一つ残念なことは、私自身の理解が伴っていないということでしょうか…(苦笑)。

これをもちまして、本質問を締め切らせていただきます。
サイトの主旨に従いましてポイントを付与させて頂きますが、お二方の善意に対して甲乙つけるものではないことを申し添えておきます。

この度は本当にありがとうございました。
どうぞ、今後ともよろしくお願いいたします。

補足日時:2007/11/05 14:06
    • good
    • 0
この回答へのお礼

taloo様、再度のご回答ありがとうございます。

> JAVA/C++のClass(JavaScriptではコンストラクター)定義+インスタンス生成の書き方もできます。
> ~ 中略 ~
> var a=pa.method2(); //a=7

動く場合と動かない場合を具体的に書いてくださったので、すぐにイメージをつかめました!


> aryの使い道がよくわかりませんが、
> 値をコピーせずに、ary自体をプライベート変数として保持しておき、値の一元管理をした方が良い様な気がします。

おっしゃられることはごもっともなのですが、今回作成したい PseudoArray の使われ方を変更することができませんので、どうしても、
var pa = new PseudoArray(param1, param2);
var hoge = pa[*]; (← 申し訳ありません。この記述が抜けておりました。)
という記述ができるオブジェクトに拘っています。
今回のような条件がない場合は、おっしゃられたように「プライベート変数として保持」という方向で考えていきたいと思います。


> *JavaScript"らしい"書き方はprototypeだと思います。

やはり、そうなんですよね。
prototype に馴染めないが故に、JavaScript に馴染めないような気がしています…(苦笑)。
書式だけに関して言えば C言語とほぼ同じということで、いきなりサンプルから JavaScript に入ったのですが、やはり根本的なところから学ぶ必要がありそうです。

とりあえずは、immovableFunc() で返ってくる結果を個々にコピーという手で進みたいと思います。

ご回答に細やかなご配慮を頂いきまして、たいへん感謝しております。
どうもありがとうございました。

お礼日時:2007/11/03 22:34

この条件だとちょっと無理がある気がします。



インスタンス生成(new Class();)するクラスは独自定義可能です。(参考URL参照)

ただ、Arrayクラスを継承したクラスの生成はかなり面倒です。Arrayクラスのメソッド・プロパティは列挙可能でない(for inループで扱えない)場合が多いため、参考URLで紹介されている継承方法は利用できません。

どうしてもやるとすればArrayクラスのメソッド・プロパティを個別に指定してコピーすることになりますが・・・。

やはり、この場合は1の方の回答が一番素直だと思います。

参考URL:http://www.tokumaru.org/JavaScript/
    • good
    • 0
この回答へのお礼

susie-t様、ご回答ありがとうございます。

やはり、無理があるのでしょうか…。
なんとなくですが、私は無茶な条件を申し上げているのではないか? という気はしているのですが…。

ですが、もう少し調査を継続したいと思いますので、さらに補足をさせてもらいます(補足ばかりで大変恐縮です。)。
メソッドやプロパティは独自のものを使いますので、Arrayオブジェクトのメソッドやプロパティは継承しなくてもかまいません。

ANo.1の補足欄で申し上げましたように、
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
という記述に一縷の望みを託したい気分です。
この意味がわかれば、なんとかできるのではないかと思っているのですが…。

引き続き、情報をお待ちしたいと思います。

それと、参考URLありがとうございます。
並行して、JavaScriptの勉強をさせていただきます。

ご回答ありがとうございました。

お礼日時:2007/11/02 14:30

function PseudoArray(param1, param2) {


var myArray = new Array;

return myArray;
}

これでいいのではないでしょうか?
newを使わずに
var pa = PseudoArray(param1, param2);
という書き方になりますが。

この回答への補足

説明不足でしたので、少々補足させていただきます。
オブジェクトPseudoArrayは、
prop1, prop2
というプロパティと、
method1, method2
というメソッドを持ちます。
したがいまして、質問のサンプルに付け加えますと、

var pa = new PseudoArray(param1, param2);
var hoge1 = pa.method1(param3, param4);
var hoge2 = pa.method2(param5, param6);

というような使われ方をします。


また、質問投稿の傍ら、継続してネット検索をしておりまして、
------------------------------
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
とすれば、Arrayなどを継承できる。
------------------------------
という記述を見かけたのですが
(ソース:http://blog.livedoor.jp/dankogai/archives/506620 …)、
正直、今の私の知識では、上記の記述を理解することができませんでした。

オブジェクト指向は、ある程度理解しているのですが
(C++でしたら、不自由せずに使える程度です)、
JavaScriptのprototypeというものに、どうも馴染めないでいる状態です。

補足日時:2007/11/02 14:09
    • good
    • 0
この回答へのお礼

taloo様、ご回答ありがとうございます。

ご回答いただいたコードに似たようなものを私も試してみたのですが、
上記補足にも記述しましたように、プロパティとメソッドを
どのようにもたせるかで躓いてしまいました。

また、
var pa = new PseudoArray(param1, param2);
という使われ方もすでに決められている状況ですので、
条件を満たす方法で、なんとかできないものかと模索しております。
条件さえみたせれば、PseudoArrayは、オブジェクトでなくともかまわなのですが…。

継続して、情報をお待ちしたいと思います。
ご回答ありがとうございました。

お礼日時:2007/11/02 14:12

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!