[過去ログ] + JavaScript の質問用スレッド vol.117 + (1001レス)
前次1-
抽出解除 レス栞

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
308
(4): デフォルトの名無しさん [sage] 2014/12/02(火) 13:27:53.03 ID:OQmm7jB2(1/3) AAS
jQueryにはbindに相当するものとして、$.proxyっていうのが有るのだけれど、
なんでbindがproxyという名前なのか昔から疑問だった。
prototypejsではbindという名前なのに。

最近その謎が解けた。それは変数にthisを代入すればいいから
bindは不要であるという話にもつながっていて、

例えば、>>293
293(12): デフォルトの名無しさん [sage] 2014/12/02(火) 03:15:02.67 ID:MjRXeq65(1/3) AAS
外部リンク:developer.mozilla.org
初心者の JavaScript プログラマーがよくやる間違いは、
あるオブジェクトからメソッドを取り出し、後でその関数を呼び出すとき、
その内側の this 値が元のオブジェクトになると考えてしまうことです
(例えば、そのメソッドをコールバック関数に使うケース)。
特に配慮しなければ、元のオブジェクトは失われてしまいます
【訳注: 取り出した関数内の this としては使えなくなる】。
その関数に元々のオブジェクトを bind() して束縛された関数を生成すれば、
この問題をきちんと解決することができます:

var x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};

module.getX(); // 81

var getX = module.getX;
getX(); // 9, この場合 "this" はグローバルオブジェクトを参照するため

// 'this' を module に結びつけた新しい関数を生成
var boundGetX = getX.bind(module);
boundGetX(); // 81
みたいなものは、bindで渡すべきじゃない。
なぜなら、getXは普通に考えると自分自身のxを返すという仕様であり、
外部から指定されるべきものじゃないから。

そして外部から指定するもの。例えばあるクラスにイベントハンドラを
設定するみたいなコード。そのイベントハンドラに匿名関数を渡すのではなく、
別のオブジェクトの関数を渡す時に、$.proxyを使ってオブジェクトをバインドする。
(普通は関数だけじゃなくてオブジェクトも指定する必要があるから)

バインドしたい時というのは、このように別のオブジェクトの関数への
プロキシとして使うことがほとんどだから$.proxyという名前なんだ。
331
(3): デフォルトの名無しさん [sage] 2014/12/05(金) 00:53:39.93 ID:lxRVtaYn(1) AAS
>>330
330(1): デフォルトの名無しさん [sage] 2014/12/04(木) 23:26:08.87 ID:tYdcY83W(4/4) AAS
bind禁止? 誰が?
一体誰にレスしてるのさ。
ちょっとアンカーつけてみな。
>>308
338
(1): デフォルトの名無しさん [sage] 2014/12/05(金) 08:21:33.54 ID:+TXyzC2W(2/4) AAS
>>308が言っているのは、

> 例えば、>>293みたいなものは、bindで渡すべきじゃない。

>>293みたいなものの話。bind全部を禁止などとは言っていない。
オブジェクトのメソッドが(意味的に)自分自身を参照したいならば
それは外部からもらうのではなく、変数に持っておけという話。
342: デフォルトの名無しさん [sage] 2014/12/05(金) 13:52:26.89 ID:I0a9lIBJ(1/5) AAS
>>336
336(1): デフォルトの名無しさん [sage] 2014/12/05(金) 07:50:03.86 ID:uibbdYqE(1) AAS
>>331
jQuery が bind 禁止している(してないけど)ように見えるのは
bind が jQuery 上の別の意味の bind と名前が被ってるから
別に native な javascript の bind を禁止している訳ではない
jQuery.prototype.bind が既にあるからという意味だよね
その方が説明としてしっくりくるし、まだ理解できる
外部リンク:api.jquery.com

>>337
337(2): デフォルトの名無しさん [sage] 2014/12/05(金) 08:18:20.31 ID:+TXyzC2W(1/4) AAS
そしてbindがproxyという名前になっているのは、
通常bindしただけで終わることはなく、
関数呼び出しまで伴うから。

call、applyともに関数を呼び出す(または適用する)
bindだけだとthisをbindするだけの意味で終わるけど
proxyならある関数に処理を転送するという意味になる。

より適切な名前であるという話。
jQuery.prototype.bind も jQuery.proxy も関数呼び出しなどしない

>>338
> それは外部からもらうのではなく、変数に持っておけという話。
>>293に関していえば、初めから getX に変数束縛してるよね
これは変数名が適切でないというだけだと思うんだけどな

var getXFromModule = getX.bind(module); // この名前なら適切

わざわざ変数束縛する手間を作っているということは、module を参照できないスコープで getX を参照したいから
module をそのまま渡せば勿論、解決するけど、参照範囲を広げたくないケースもある
その場合に Function.prototype.bind は有効となる

>>340
340(1): デフォルトの名無しさん [sage] 2014/12/05(金) 11:30:16.33 ID:yozkxrw8(1/2) AAS
>>331
その話は「bind禁止」じゃなくね

・大概の場面はbindじゃなくても出来る
・残りの限られた場面を表すものとしては、proxyのがしっくりくる

という話にしか読めんな
改めて読むと「bind禁止」は言いすぎだった、すまん
ただ、>>308が主張しているイベントハンドラ関数に指定するケースでは bind でも有効だし、proxy が適切って理屈は理解できないね
jQuery.proxy は new 演算子に対応してないし、関数がオーバーロードされてるし、多くの特性が bind とはかけ離れてる
別種の機能だから、bind という名前にしなかったのは理解できるけどね
外部リンク:api.jquery.com
344
(2): デフォルトの名無しさん [sage] 2014/12/05(金) 14:41:34.64 ID:I0a9lIBJ(2/5) AAS
>>343
343(2): デフォルトの名無しさん [sage] 2014/12/05(金) 14:06:15.50 ID:LEC5N9e7(1/2) AAS
なんかbindで盛り上がってるけど、>>293はおかしな突っ込みどころなんて全く無く至って正論
> var getXFromModule = getX.bind(module); // この名前なら適切
いやいや、>>293
> var boundGetX = getX.bind(module);
で全く問題ないじゃん

他の変数(selfなど)にオブジェクトを代入しといて使うとか言ってる奴が居るが
>>293
> getX: function() { return this.x; }
のthis.xをself.xとかに書き換える無意味な変更が生じる
bindを使う使わないなんて議論する余地なんてない
boundGetX は直訳すると「縛られたGetX」だけど、何に bind されてるか、わかりずらいかなーと思った

var boundGetX = getX.bind(module),
var boundGetX = getX.bind(hoge);

どちらも boundGetX で意味は通るけど、何にbindされてるかわからない
>>308の「getXは普通に考えると自分自身のxを返すという仕様であり」あたりは対象が不明だからそう思うのであって、module という対象が明確であればなんら問題はない
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.069s