お世話になっております。現在JavaScriptの勉強をしております。
その一環としてPrototype.js ver 1.6.1 を解読しているのですが
Enumerable 等のメソッドで出てくる return でリテラル関数を指定するような部分が多々見受けられるのですが…この意味がイマイチ感覚がつかめず困っています。
例:Prototype.js 702行目付近
Enumerable = (function(){...
の collectメソッド(743行目付近)
function collect(iterator, context) {
iterator = iterator || Prototype.K;
var results = [];
this.each(function(value, index) {
results.push(iterator.call(context, value, index));
});
return results;
}
などの
this.each(function(value, index) {
results.push(iterator.call(context, value, index));
}
部分で
function(value, index)...
とあるvalue, index はどこでどれから指定されるのかがよくわかりません。
[1,2,3,4].collect(a,b);
と呼び出した場合、collect(a,b){... と呼ばれますが value と indexには何がどうやって指定されるのでしょうか?
このような記法が把握できず、混乱を極めている状態です。
どなたかお手数ですがお教え願えないでしょうか?
よろしくお願いいたします。
No.5ベストアンサー
- 回答日時:
prototype.jsからコードを抜き出して読み易くまとめてみました。
Arrayオブジェクトしか扱えませんけど。
//- Arrayオブジェクトの拡張 -------------------------
Array.prototype._each = function (iterator) {
for (var i = 0, length = this.length; i < length; i++) {
iterator(this[i]); // callback関数第一引数 (this[i])
}
};
Array.prototype.each = function (iterator, context) {
var index = 0;
this._each(function(value) {
iterator.call(context, value, index++); // callback関数第二引数 (index++)
});
}
Array.prototype.collect = function (iterator, context) {
var results = [];
this.each(function(value, index) {
results.push(iterator.call(context, value, index));
});
return results;
}
//- Arrayオブジェクトの拡張ここまで ------------------
var arr = [ 2, 4, 6, 8 ];
//各要素を2倍した値に置き換えその結果を返す
var callback = function (v, i) { return this[i] = v * 2; };
var results = arr.collect(callback, arr /* 関数内this値 */);
alert('collectメソッドの戻り値: ' + results);
alert('arrの値: ' + arr);
//- ここまで -----------------------------------------
//Array.collect()に限るなら
Array.prototype.collect = function (iterator, context) {
var results = [];
for (var i = 0, length = this.length; i < length; i++) {
results.push(iterator.call(context, this[i], i));
}
return results;
}
Function.prototype.call
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma26 …
Function.callメソッドさえ抑えれば難しくないはずです。
この回答への補足
ご回答いただき誠にありがとうございます。
callback変数に関数オブジェクトを代入することで
ずいぶん感覚がつかみやすくなりました。
何となくわかってきた気がします。
要はEnumerable の定義でのfunction(value, index)は
「Enumerable をインタフェースに持つクラスはそのメソッド使う時は
こういうフォーマットの評価・処理関数をしてくださいな」
ということなのでしょうか?
>var arr = [ 2, 4, 6, 8 ];
>//各要素を2倍した値に置き換えその結果を返す
>var callback = function (v, i) { return this[i] = v * 2; };
>var results = arr.collect(callback, arr /* 関数内this値 */);
↓
>Array.prototype.collect = function (iterator, context) {
>var results = [];
>this.each(function(value, index) {
>results.push(iterator.call(context, value, index));
>});
↑のthis.each(fuction(v, i){results.puch(callback.call(context, v, i);}
となるイメージでよろしいのでしょうか?
No.4
- 回答日時:
No.1さらに気づいた事
iterator.call(context, value, index)
の部分は単にiteratorを実行しているのではなく、
iteratorクラスの継承でvalueとindexをiterator内で
使える用にしているという事かなあ。
想像ばかりの回答で、すんません。
有識者の回答を待ちましょう....
たびたびご回答いただきありがとうございます。
Arrayに関しては_eachを実装しているので分かりやすいので逆にたどればEnumerableとの動作連携は分かる気がします。
のんびり待ちます…
その前に自力で把握できればいいのですけどね。(苦笑
No.3
- 回答日時:
No.1です。
私の回答ちょっと違ってました。オブジェクト指向にそんなに詳しいわけじゃないんですが。
「Enumerableでとなっているの所のvalue はどこから来るんだ?」
valueはやはりthisで受け渡されていくような気がします。
Enumerable.collect(iterator)はリストEnumerableを返すのですよね。
ret=[1,2,3,4].collect(function(val,idx){return val+idx;});
だとcollect(){}の中でthisは[1,2,3,4]ですよね
このthisが、this.each(function(value, index) {
results.push(iterator.call(context, value, index));
});
でeach(){}で処理され、each(){}の中のthisも
[1,2,3,4]になります。さらにeachの中で
this._each(function(value) {
iterator.call(context, value, index++);
});
となっているので、this [1,2,3,4] がそのまま_eachで処理されます。
よって_each(){}の中のthisも[1,2,3,4]のことになるので
_each: function(iterator) {
for (var i = 0, length = this.length; i < length; i++)
iterator(this[i]);
}
iterator(this[i]); で、[1,2,3,4] の i 番目がiteratorで処理されます、
iterator関数内に引き渡す際の引数名が単にvalueなのではないかと、
No.2
- 回答日時:
No.1補足
this.eachのeachもprototype.jsのメンバーで、
var Enumerable = {
each: function(iterator, context) {
var index = 0;
try {
this._each(function(value) {
iterator.call(context, value, index++);
});
} catch (e) {
if (e != $break) throw e;
}
return this;
}
となっており、さらに別のところで
Object.extend(Array.prototype, {
_each: function(iterator) {
for (var i = 0, length = this.length; i < length; i++)
iterator(this[i]);
}
ますから、indexはこの仕組みの中で作られて、使われるわけですね。
この回答への補足
お世話になります。
Object.extend(Array.prototype, {
_each: function(iterator) {
for (var i = 0, length = this.length; i < length; i++)
iterator(this[i]);
}
のところは感覚として分かるのです。配列インスタンス(this)の各要素にiteratorを実行するのだと…
//---
each: function(iterator, context) {
var index = 0;
try {
this._each(function(value) {
iterator.call(context, value, index++);
});
} catch (e) {
//---
Enumerableでとなっているの所のvalue はどこから来るんだ?
となってしまうのです。_each(以降の部分がiterator?としてEnumerableを追加されたクラスの_each()へ行くのかな?と
なんだか迷走してしまうんです。
お手数ですがお答えいただけたら幸いです。
No.1
- 回答日時:
質問の意味がよくわからないのですが...
[1,2,3,4].collect(a,b);と使うのは変です。a,bは何ですか?
列挙型オブジェクト.collect(イテレータ関数);
と使われるはずです。
function collect(iterator, context){}
の内部で引き渡したイテレータ関数が
results.push(iterator.call(context, value, index));
で、iterator()の名前で呼び出されて、結果をresultsに格納して
return results;で返しています。
iterator.call(context, value, index)時の
valueとindexは、
this.each(function(value, index) {
}
内にありますから、
thisのそれぞれの配列要素と要素キーです。
thisはcollect()のを呼んだやつの列挙型オブジェクトです。
つまり
[1,2,3,4].collect(function(a,b){alert(a[b])});
ならaがvalueで[1,2,3,4]、bがindexでその配列の
要素キー 0,1,2,3 をbでアクセス出来る
という事では....
この回答への補足
お世話になっております。
言葉足らずで申し訳ありません。collect()自身に疑問があるわけではなく、
>iterator.call(context, value, index)時の
>valueとindexは、
>this.each(function(value, index) {
>}
>内にありますから、
>thisのそれぞれの配列要素と要素キーです。
>thisはcollect()のを呼んだやつの列挙型オブジェクトです。
>つまり
>[1,2,3,4].collect(function(a,b){alert(a[b])});
>ならaがvalueで[1,2,3,4]、bがindexでその配列の
>要素キー 0,1,2,3 をbでアクセス出来る
>という事では....
とご回答いただいたわけですが、まさにそこが疑問点なのです。
[1,2,3,4].collect(function(a,b){alert(a[b])});
ならaがvalueで[1,2,3,4]、bがindexでその配列の
要素キー 0,1,2,3 をbでアクセス出来る
のaがなぜvalueの[1,2,3,4]になり、bがindexになるのか?
というところが分からないのです。
「そうなるんだよ」と言われたらそれまでなのですが、
なぜそうなるのかおわかりでしたらお教え願えないでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/30 09:10
- JavaScript javascriptで移動ボタンを押した際に遷移するボタンを追記したい 1 2022/11/29 03:02
- JavaScript jqueryを使ったスムーススクロールのコードを書いたのですが、HTMLコード内にある、a butt 2 2022/04/14 10:59
- JavaScript console.logがどうしても2つ機能しないのでアドバイスをくださいお願いします 2 2022/07/07 22:13
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- JavaScript javascript作成してます。ラジオボタンで判定するコードを書いてます。 1 2023/07/18 11:03
- JavaScript HTMLでJavaScriptを使ってパスワードの強化判定のプログラムを作成しています。 一通り作っ 2 2022/10/19 01:41
- JavaScript javascriptのちょっとした動作不良(原因は突き止めたのですが) 1 2023/06/15 19:58
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
jslintのエラーについて質問
-
function(e)の意味を教えてくだ...
-
idを使わずにonclickで自身の要...
-
functionから別のfunctionを実...
-
関数名をテキストから読み込む...
-
if文等のブロック内での関数宣...
-
google apps scriptの終了のさせ方
-
C#OpenCv V4にのエラーに関する...
-
onchangeイベントを使ってspan...
-
同じIDで定義した要素の配列を...
-
1日1回引けるJavaScriptおみく...
-
Click回数を数え、規定された回...
-
canvas上で画像を移動する方法...
-
C# .NET DataGridView の行を追...
-
var_dumpのdump意味はを知りた...
-
googleスプレッドシートのApps ...
-
javascriptで文字挿入でtoggle...
-
javascript 特定のタグのidの存...
-
GASでundefinedエラーが出ます
-
FireFoxのjavascriptで自動でキ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
functionから別のfunctionを実...
-
idを使わずにonclickで自身の要...
-
関数でy=g(x)のgとは何の略です...
-
jslintのエラーについて質問
-
jQueryの :not() .not() が有効...
-
クリックすると上に開くアコー...
-
jQueryのプラグイン「Skitter」...
-
関数名をテキストから読み込む...
-
小数点以下を5刻みで表示
-
XMLHttpRequestでキャッシュを...
-
jQueryでzipを解凍読み込みする...
-
Matlabで自作関数をオーバーロード
-
javascript(jQuery)でセル内...
-
要素名がスペースを含む場合のj...
-
ページ内に複数表がある場合のT...
-
処理前の「お待ちください」
-
JS 頭文字が大文字について
-
HTML5でファイルドラッグ&ドロ...
-
Javascriptリアルタイムエラー...
-
getElementByIdを使用したグロ...
おすすめ情報