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

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

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

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

jQuery

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

Q&A

解決済

2回答

19680閲覧

【jQuery】引数にthisを渡せない

k499778

総合スコア599

JavaScript

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

jQuery

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

0グッド

0クリップ

投稿2016/03/23 11:35

編集2016/03/23 15:57

現在開発をしていてjqueryで
clickイベントの処理を行っていました。

そのクリックfunction内ではthisを使って、
クリックしたセレクタを指定することはできたのですが、
そのクリックfunction内にfunction(関数)を書き、その引数にthisを渡すとエラーになりました。

もちろんそのクリックfunction外に使いたい関数を定義し、その引数にもthisと記述しています。

このやり方は間違っているのでしょうか?
なぜエラーになったのか教えていただけるとありがたいです。


追記

例えばこのような場合です。

HTML

1 2<!DOCTYPE html> 3<html> 4 5<head> 6 <meta charset="UTF-8"> 7 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 8 <style> 9 .aaa { 10 width: 150px; 11 height: 50px; 12 background-color: #EFE; 13 border: solid 1px #CCC; 14 position: absolute; 15 } 16 17 .ddd { 18 width: 150px; 19 height: 50px; 20 background-color: pink; 21 border: solid 1px pink; 22 position: absolute; 23 } 24 </style> 25</head> 26 27<body> 28 <label class="aaa"> 29 <span class="bbb"></span> 30 <input type="hidden" class="ccc">りんご 31 </label> 32 <br> 33 <br> 34 <br> 35 <label class="aaa"> 36 <span class="bbb"></span> 37 <input type="hidden" class="ccc">いちご 38 </label> 39 <br> 40 <br> 41 <br> 42 <label class="aaa"> 43 <span class="bbb"></span> 44 <input type="hidden" class="ccc">ぶどう 45 </label> 46 <br> 47 <br> 48 <br> 49 <label class="ddd"> 50 <span class="bbb"></span> 51 <input type="hidden" class="ccc">りんご 52 </label> 53 <script> 54 $(function() { 55 $(".aaa").on("click", function() { 56 //処理1。関数に切り出さず、直接書くとエラーにならない 57 // this.ownerDocument.querySelector('.ddd').lastChild.data = this.lastChild.data; 58 test(this); 59 60 //処理2。関数に切り出さず、直接書くとエラーにならない 61 // var txt = $(this).text(); 62 // $(".ddd").contents().filter(function(){ return this.nodeType === this.TEXT_NODE }).remove(); 63 // $(".ddd").append(txt); 64 test2(this); 65 }); 66 }); 67 68 //関数に切り出すとエラーになる 69 function test(this){ 70 this.ownerDocument.querySelector('.ddd').lastChild.data = this.lastChild.data; 71 } 72 73 //関数に切り出すとエラーになる 74 function test2(this){ 75 var txt = $(this).text(); 76 $(".ddd").contents().filter(function(){ return this.nodeType === this.TEXT_NODE }).remove(); 77 $(".ddd").append(txt); 78 } 79 </script> 80</body> 81 82</html> 83

追記2

処理1は動く。処理2は想定の動きにならない。
「直接書いたコード」と「関数を呼び出した場合」で動きが変わる。
文字をremoveできていない。

HTML

1<!DOCTYPE html> 2<html> 3 4<head> 5 <meta charset="UTF-8"> 6 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 7 <style> 8 .aaa { 9 width: 150px; 10 height: 50px; 11 background-color: #EFE; 12 border: solid 1px #CCC; 13 position: absolute; 14 } 15 16 .ddd { 17 width: 150px; 18 height: 50px; 19 background-color: pink; 20 border: solid 1px pink; 21 position: absolute; 22 } 23 </style> 24</head> 25 26<body> 27 <label class="aaa"> 28 <span class="bbb"></span> 29 <input type="hidden" class="ccc">りんご 30 </label> 31 <br> 32 <br> 33 <br> 34 <label class="aaa"> 35 <span class="bbb"></span> 36 <input type="hidden" class="ccc">いちご 37 </label> 38 <br> 39 <br> 40 <br> 41 <label class="aaa"> 42 <span class="bbb"></span> 43 <input type="hidden" class="ccc">ぶどう 44 </label> 45 <br> 46 <br> 47 <br> 48 <label class="ddd"> 49 <span class="bbb"></span> 50 <input type="hidden" class="ccc">りんご 51 </label> 52 <script> 53 $(function() { 54 $(".aaa").on("click", function() { 55 //処理1。関数に切り出さず、直接書くとエラーにならない 56 // this.ownerDocument.querySelector('.ddd').lastChild.data = this.lastChild.data; 57 // test(this); 58 59 //処理2。関数に切り出さず、直接書くとエラーにならない 60 // var txt = $(this).text(); 61 // $(".ddd").contents().filter(function(){ return this.nodeType === this.TEXT_NODE }).remove(); 62 // $(".ddd").append(txt); 63 test2(this); 64 }); 65 }); 66 67 //関数に切り出すとエラーになる 68 function test(_this){ 69 _this.ownerDocument.querySelector('.ddd').lastChild.data = _this.lastChild.data; 70 } 71 72 //関数に切り出すとエラーになる 73 function test2(_this){ 74 var txt = $(_this).text(); 75 $(".ddd").contents().filter(function(){ return _this.nodeType === _this.TEXT_NODE }).remove(); //ここがうまくいっていない 76 $(".ddd").append(txt); 77 } 78 </script> 79</body> 80 81</html> 82

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

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

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

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

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

guest

回答2

0

ベストアンサー

this は予約語なので引数の名前で this は指定できないです
_this とかにすればいいと思います

投稿2016/03/23 15:34

ryls-nmm

総合スコア633

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

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

k499778

2016/03/23 15:53

回答ありがとうございます! そうなんですね。_thisにするとエラーが消えうまくいきました! ただ処理2が「直接書いた動き」と「関数を呼びたした時の動き」で変わってしまいます。 もしよろしければ教えていただけないでしょうか? 追記2に実際に修正したコードを載せます。
ryls-nmm

2016/03/23 16:03 編集

$(".ddd").contents().filter(function(){ return this.nodeType === this.TEXT_NODE }).remove(); で filter に渡す無名関数ないで this を使っています 関数の中では勝手に this が変わってしまうので「直接書いた」方では意図しない動きになってるはずです this は window (グローバル領域) を指しているので nodeType も TEXT_NODE も存在しなく undefined 同士で true が返ってるはずです _this にしたほうでは、 filter に渡した関数の中でも _this が変わらず test2 関数の引数で受け取った_this になっています
k499778

2016/03/23 22:49 編集

返答ありがとうございます。 どちらかと言うと、 「直接書いた」方が意図している動きになっていて 「関数に切り出した(_this)」の方が意図しない動きになってしまいます。 前回投稿した質問の動きなのですが https://teratail.com/questions/30449 「直接書いた」方はremoveされて、 「$(".ddd")のボックスの中の文字」がちゃんと変わるのですが、 「関数に切り出した(_this)」の方では、removeされず、「$(".ddd")のボックスの中の文字」が増えていってしまいます。 デベロッパーツールで「_this.nodeType」と「_this.TEXT_NODE」を見た限り、 「直接書いた」方と同じ値が入っていたのでなぜうまくいかないのかわからない次第です。 もしアドバイスいただけたらありがたいです。
ryls-nmm

2016/03/24 14:33

すみません私もちゃんと読んでませんでした。 文字の要素(テキストノード)を remove したいのですね。 正しくはこうです $(".ddd").contents().filter(function(i,e){ return e.nodeType === Node.TEXT_NODE }).remove(); 説明しますと $(".ddd").contents() では、 .ddd の子要素一覧を持ってきます それは <span class="bbb"></span> <input type="hidden" class="ccc"> りんご の3つといくつかの空白文字列のテキストノードです これらの中から filter をするわけですが、ここでは span や「りんご」などのそれぞれの要素に対してチェックをしないといけないです それらは filter に渡す関数の引数でとることができます 2番めの引数の e に span や りんご などが入っています なので e.nodeType と Node.TEXT_NODE が等しい物を残せば文字列だけを選択できるので remove で削除できます Node.TEXT_NODE は e.TEXT_NODE でも同じ値です --- 直接書いた場合でも、関数に分けた場合でも filter に渡した関数の中での `this` は window です なので filter の結果はすべての値がそのまま入っています そのため、`_this` にしない方では 全部の要素(input も含めて)が消えてから「りんご」が追加されているのでうまく行ってるように見えます `_this` のほうでは span や「りんご」ではなく、 .ddd の要素に対して テキストノードかのチェックを繰り返すので全部違うので filter の結果は空になり何も remove されないということになります --- ただ 文字列を置き換えたいだけなら、「りんご」などを <span class="fruit-name"></span> で書こんで、 $(".ddd .fruit-name").text("みかん") としたほうが楽だと思います なんか凄く長くなってしまいました すみません
k499778

2016/03/24 23:16 編集

詳しく丁寧に説明していただきありがとうございます。 確かに $(".ddd").contents().filter(function(i,e){ return e.nodeType === Node.TEXT_NODE }).remove(); だと関数の中でも同じ動きが実現できました。 ただ少し腑に落ちない点がございます。 1つ目 >直接書いた場合でも、関数に分けた場合でも filter に渡した関数の中での `this` は window です 「`_this` でない直接書いた方」では、`this` は 「window」 ではなく、「label.aaa」つまり「選択したラベル」が入っています。 2つ目 function(i,e)の「i」を消すと、spanタグやinputタグも消えてしまうのはなぜでしょうか? 「i」について調べて、i番目などを指すときに使うものだと思っています。 またこのコードで「i」を使っていないのに影響していることが不思議です。 ちなみに、コードは「=== e.TEXT_NODE })」です。 3つ目 function(i,e)の「i」を消し、「=== e.TEXT_NODE })」のときと「=== Node.TEXT_NODE })」のときで処理の内容が変わるのはなぜでしょうか? 「=== e.TEXT_NODE })」のとき ・spanタグやinputタグも消えてしまう 「=== Node.TEXT_NODE })」のとき ・removeされず、文字がどんどんappendされてしまう 4つ目 そもそも一番知りたいのですが、 関数の引数に「this」を渡したい時 普通の場合は、「_this」のように予約語を避けた名前をつければ、直接書いたコードのまま関数に切り出せるが、 今回のように「this」の中身が関数に切り出すと変わってしまう場合は、直接書いたコードを一部変更しなくてはいけない。 という認識でよろしいでしょうか? 私もかなり長くなってしまっているので、解決済みのスレに対して追加で聞きすぎているので別のスレを立てます。 https://teratail.com/questions/30668 よければ回答いただけたらと思います。
ryls-nmm

2016/03/26 03:47

jQuery では this がbindされているのですね。これは私の勘違いでした、すみません。 新しいスレではベストアンサーも決まってることですし私はこれまでにしておきます
guest

0

関数の引数に this を渡すとエラーになるという事ですが、具体的にどんなコードを書いていますか。
jQuery でコールバック関数に引数を渡す方法はいくつかあります(個人的には event.data を推します)。

Re: k499778 さん

投稿2016/03/23 12:15

think49

総合スコア18162

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

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

k499778

2016/03/23 15:30

回答有り難うございます! 追記しましたので見てもらえればと思います。
think49

2016/03/23 23:46

関数オブジェクトを指定すれば引数束縛する必要がなくなりますね。 ついでに event オブジェクトの扱いについても学んでおくといいかもしれません。 jQuery('.aaa').on('click', test); function test (event){ this.ownerDocument.querySelector('.ddd').lastChild.data = this.lastChild.data; }
k499778

2016/03/24 03:09

回答ありがとうございます! 関数オブジェクトのやり方は知りませんでした。 イベントオブジェクトの使い方についても勉強してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問