🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

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

Q&A

解決済

2回答

652閲覧

自己定義関数の中に変数を埋め込む方法

SugiuraY

総合スコア318

JavaScript

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

0グッド

0クリップ

投稿2019/11/04 13:15

編集2019/11/04 15:24

下記のように自己定義関数sampleの中において、alertの中に変数として
hoge+messageを代入してsample("push")によって、結果として"hello"を返したいのですが
"push_message"として文字列が返されます。

この関数の中のhoge+'_message'を変数として使用したいのですが
どのようにすれば良いのでしょうか?

html

1<button class="push">push</button>

javascript

1const push_message ="hello"; 2sample("push") 3 4function sample(hoge){ 5$('.'+hoge).on('click',function(){ 6 alert(hoge+'_message')7 }) 8}

追記

なぜそのようにしたいのかという目的についてご指摘があったため、下記の通り、実際の状況を踏まえて、目的とともに内容を追記させていただきました。

実際にはconst push_messageは配列でこれに対する処理を自己定義関数内で書いております。

html

1<button class="ary1">click</button>

ここで自己定義関数でそれぞれの配列に対して処理を定義する場合に以下のようにするよりも

javascript

1var ary1_a=[]; 2var ary2_a=[]; 3var ary3_a=[]; 4 5function sample (cls, cls_a){ 6$(".+cls).on('click',function(){ 7cls_a.push(/*something*/) 8}) 9}

例えば以下のように**引数を減らしたほうが後々見通しが良いためというのが目的です**。

javascript

1var ary1_a=[]; 2var ary2_a=[]; 3var ary3_a=[]; 4 5function sample (cls){ 6$(".+cls).on('click',function(){ 7(cls+"_a").push(/*something*/) 8}) 9}

たまたま、以下の条件を満たすため、このような対応をしたいと感がているところです。

  • 2つの引数となるべき一部の文字列(cls)が重複している
  • その後に続く文字列(_a)が適用すべき関数において共通である

なお、eval(hoge+'_message')で対応することは可能かと思うのですが、一般的にevalを使わなくて良い方法があるのであれば仕様は控えるべきと、学んだことがあるため今回使用はしていません

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

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

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

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

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

otn

2019/11/04 13:32

何のために push_message ="hello" みたいな変数を用意して、変数名の一部を動的に指定したいのかの目的によって、解決方法が変わってくると思います。
kei344

2019/11/04 13:38

「変数として使用したいのですが」とは「どう使いたいのか」も提示してください。出来れば、何のためにそういう使い方をしたいのかも具体的にかかれたほうが、回答も付きやすいと思います。
SugiuraY

2019/11/04 13:48

実際にはconst push_messageは配列でこれに対する処理を自己定義関数内で書いております。 var ary1_a=[] var ary2_a=[] var ary3_a=[] <button class="ary1">click</button> ここで自己定義関数でそれぞれの配列に対して処理を定義する場合に以下のようにするよりも function sample (cls, cls_a){ $(".”+cls).on('click',function(){ cls_a.push(/*something*/) }) } 例えば以下のように引数を減らしたほうが後々見通しが良いためというのが目的です。 function sample (cls){ $(".”+cls).on('click',function(){ (cls+"_a").push(/*something*/) }) } たまたま、以下の条件を満たすため、このような対応をしたいと感がているところです。 - 2つの引数となるべき一部の文字列(cls)が重複している - その後に続く文字列(_a)が適用すべき関数において共通である なお、eval(hoge+'_message')で対応することは可能かと思うのですが、一般的にevalを使わなくて良い方法があるのであれば仕様は控えるべきと、学んだことがあるため今回使用はしていません。
kei344

2019/11/04 13:52

この「質問への追記・修正の依頼」の部分はデフォルトで表示されませんので、質問本文に追記することをお勧めします。
SugiuraY

2019/11/04 14:10 編集

kei344様 コメントありがとうございます。 承知をしました、本文に追記をさせていただきます。
think49

2019/11/04 14:48

「追記」のコードがコードブロックで括られていないようなので、修正して下さい
guest

回答2

0

ベストアンサー

event.data

イベントハンドラ関数に値を渡すのであれば、jQueryには event.data が用意されています。

JavaScript

1'use strict'; 2const foo = 'push'; 3jQuery('.' + foo).on('click', new String(foo), event => console.log(event.data + '_message'));

他に、data-*属性に埋め込む手もあります。

引数を減らす

JavaScript

1function sample (cls) { 2 $("."+cls).on('click',function(){ 3 (a[cls]).push(/*something*/) 4 }) 5}

クラス名と変数名(プロパティ名)を一つの変数にまとめて、引数を減らす設計は良いとは思いません。
クラス名と変数名は別の概念であり、同じ名前にする必然性はありません。
同じ名前にしてしまうと、後で変数名を変えた時にクラス名まで変えなくてはなりません。

変数名を一つの名前で固定すると、関数と変数の間に依存関係が出来ます。
変数のスコープは出来るだけ狭くし、参照透過性を持つ設計にするのが、可搬性/汎用性の観点から好ましいと感じます。

data-*属性 + event.data

HTML

1<input type="button" class="sample" value="push1" data-index="0"> 2<input type="button" class="sample" value="push2" data-index="1"> 3<input type="button" class="sample" value="push3" data-index="2"> 4<script> 5'use strict'; 6function handleClick (event) { 7 console.log(event.data[jQuery(event.target).data('index')]); 8} 9 10function addClickHandler (selectorText, data, handler) { 11 jQuery(selectorText).on('click', data, handler); 12} 13 14addClickHandler('.sample', ['sample1','sample2','sample3'], handleClick); 15</script>

Re: SugiuraY さん

投稿2019/11/04 14:27

編集2019/11/05 13:55
think49

総合スコア18189

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

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

SugiuraY

2019/11/04 14:41

コメントありがとうございます。 1) data-*属性に埋め込むというのは単純ながら盲点でした、、こちらの方法で対応しようと思います。 2) 一方でevent.dataはJqueryeventの中のクリックイベントの結果として値を取得するという点でご教示いただいたと思うのですが、これも1)と同じように「文字列を変数として扱う」という直接的な方法ではなく「このようにクリックイベントで取得した値で処理する方法もあります」という意味合いでご教示いただいたという理解でよろしいでしょうか? 実際に以下を動作させても当然、even.dataのは"push"を返すのでalert()は"hello"を返す訳ではないのでそのように理解いたしました。 <button class="push">push</button> 'use strict'; const foo = 'push'; const foo_message ="hello"; jQuery('.' + foo).on('click', new String(foo), event => alert(event.data + '_message'));
think49

2019/11/04 14:53

回答時点で「追記」は読んでいません。 配列が必要なら、配列を event.data に渡して、引数で受け取って下さい。 変数名はグローバル変数など、何らかのプロパティになっていなければ、文字列参照は出来ません。 {} や [] のプロパティとする事で文字列参照が可能となりますが、ただデータが必要なだけなら、オブジェクトをそのまま渡しても十分だと思います。 jQuery.data や WeakMap 等、要素にデータを紐付けする方法はいくつかありますが、ハンドラ単位、要素単位のどちらで紐付けしたいのか不明なので、何ともいえません。
think49

2019/11/04 14:55

正確な情報が必要な場合は、必要十分な要件を掲示して下さい。 小出しにされると、回答に困ります。
SugiuraY

2019/11/05 01:01 編集

質問の方法についてはお詫び申し上げます。 「変数に文字列を使用せざる得ない場合にはどのように指定すれば良いのですか」ということをご質問したかったのですが、結果的に何がやりたいのですかという問に回答するうちにそもそも違う方法を採用すべきではないかというアドバイスをいただいている状況なのかと理解しております。 以下は個人的に理解が追いついていない中でのなんとか頭を整理させているところございます。 (otn様のご回答について) 「変数に文字列を代入してそれを変数として参照する」方法ではなく 「配列のデータの持ち方」を変更する方法で結果的に最終的な目的である「引数を1つにして関数を作ることができる」というアドバイスと理解いたしました。 (think49様のご回答について) 「変数に文字列を代入してそれを変数として参照する」による方法ではない違う方法をご提案いただいているところまで理解しております。一方、当該方法に対して一つのご回答として "変数名はグローバル変数など、何らかのプロパティになっていなければ、文字列参照は出来ません" という点をアドバイス頂いているものと整理し理解することができました。 その場合、他の方法によって関数の引数を減らす方法を模索することになりますが アドバイスをいただいたevent.dataの方法等でご教示いただいている方法が何故、これに寄与するのかがまだどうしてもすぐには理解できないため、落ち着いて考えるお時間をください。もしそれがわかれば現時点で理解できていない最終段落の "ハンドラ単位、要素単位のどちらで紐付けしたいのか不明なので"という点も理解することができると思います!。 質問方法の不手際及び理解に時間がかかってしまう点について、改めてお詫び申し上げます。
kei344

2019/11/04 15:51

To: SugiuraYさん 私まだ回答してません。
SugiuraY

2019/11/04 16:54

失礼いたしました。 「変数名は・・・何ともいえません。」のコメントが最終的なご回答と思慮いたしました。 また、ご回答をお待ち申し上げます。
kei344

2019/11/04 16:57

To: SugiuraYさん 回答者の名前を確認してください。
SugiuraY

2019/11/04 23:12

コメント有難うございます。 それはotn様の内容をこちらに整理記載する点についてのご指摘でしょうか? 上述の文脈で当該内容をそれぞれの回答者様の欄に急に書き分けることは、後に見る方が流れを理解しづらくなることに対する配慮です。 それでもとおっしゃるのであれば、記載欄を編集いたします。 宜しくお願い申し上げます。
think49

2019/11/04 23:54

@SugiuraY さん 私の名前は「@think49」です。 > "変数名はグローバル変数など、何らかのプロパティになっていなければ、文字列参照は出来ません" ページ検索すれば、それは私(@think49)のコメントである事が分かります。 青を基調としたアイコンを見て、@kei344さんと誤認したのでは? アイコンはあてにせず、「名前」を確認して下さい。
SugiuraY

2019/11/05 01:01

大変失礼いたしました。いま辻褄が合いました。 完全に私の誤認でございます。ご迷惑をかけたお二方にお詫びいたします。 以後気を付けます。 コメント中のお名前についても修正させて頂きます。 宜しくお願い申し上げます。
SugiuraY

2019/11/06 00:15

think49様 コメントありがとうございます。 ①「クラス名と変数名(プロパティ名)を一つの変数にまとめて、引数を減らす設計」につきまして 本件、仰る通りでした。私の場合ご記載いただいた内容の反対のケースでクラス名を変更したのですが、当然関数が動作しなくなるので、とてもメンテナンスしづらいことに気づかされました。安易に引数を減らすという考え方がまたバグの温床になるという場合があることについて学ぶことができました。 ②data-*属性 や event.dataにつきまして 要素から特定の値を取得する場合にJqueryでこのような方法があることを学ぶことができました。これまでclass="sample"から特定の値を取得する場合、無理やりid="data"を設定し以下のような形で取得させたりしていました。(お恥ずかしいのですが、当然html・DOM構造上望ましくないやり方です) $('.class').on('click',function(){ $(this).attr('id')}) イベントハンドラ関数への値の渡す方法の幅が広がり、活用することができると思います。 ③、配列を event.data に渡して、引数で受け取る。 自分で動作を確認することでやっと仰っている意味が分かりました。 コールバック関数(handler)を中に書かないと自分はまだ簡単に読み解けないので下記は変形していますが、クリックイベントで取得した属性値によって、引数の中の配列( ['sample1','sample2','sample3'])のいずれかを取得するということですね。。なるほど。これまでの自分の知識と想像力では絶対に生み出すことができなかったコードなので、大変勉強になりました。 addClickHandler('.sample', ['sample1','sample2','sample3']); function addClickHandler (selectorText, data, handler) { jQuery(selectorText).on('click', data, function (event) { console.log(event.data[jQuery(event.target).data('index')]);} );} また同時に理解できなかったデータの紐づけについては、この配列の要素たちを直接クリックされる要素に備えるのか又はハンドラ関数の中に上記のように持たせるのかという意味で解釈することができました。(推察が間違っていたら申し訳ございません。) ④文字列を変数として参照する方法につきまして 結果的に当初見つけたeval()によって、これを実行することができることがわかりましたが、調べていくと処理速度やセキュリティの面からやはり望ましくないことがわかりました。eval(hoge+'_message')とする方法である。加えて①の設計の面からも今回の件に関しては望ましくはないので、evalでできることはわかったが使用すべきではないという判断で決着しようと思います。 多くの知見をご提供いただき誠に感謝いたします。 最後になりますが厚い御礼を申し上げます。
guest

0

実際には 。。。。。。

ということであれば、

JavaScript

1var ary1_a=[]; 2var ary2_a=[]; 3var ary3_a=[];

のような変数を作ってはいけません。

JavaScript

1const a = {"ary1":[], "ary2":[], "ary3":[]}; 2 3function sample (cls){ 4 $("."+cls).on('click',function(){ 5 (a[cls]).push(/*something*/) 6 }) 7}

ですね。

なお、sampleを「自己定義関数」と呼ぶのは違和感があります。

投稿2019/11/04 13:58

otn

総合スコア85882

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

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

SugiuraY

2019/11/04 14:19

コメントありがとうございます。 申し訳ございません、省略すべきでない点を省略しておりました。以下のような状況です。 var ary1_a=[1,2,3]; var ary2_a=[4,5,6]; var ary3_a=[7,8,9]; 従って問題は尾ヒレのようについてくる_aをfunctionの中でどのように表現するかと言う点でございました。 また一点ご指摘にあった「自己定義関数」についてですが Javascriptに標準で備わっているもの「標準関数」「標準メソッド」 と言う表現に対して自分自身が作り出したものを 「自己定義関数」や「ユーザー定義関数」 という名称で慣れてきたのですが、一般的にはこの後者の類はどのように呼んでいらっしゃるのでしょうか? よろしくお願いもうしあげます。
otn

2019/11/04 14:37

> 省略すべきでない点を省略しておりました。以下のような状況です。 本質的な違いは無いと思いますが。 > 一般的にはこの後者の類はどのように呼んでいらっしゃるのでしょうか? 普通は単に「関数」だと思います。「ユーザー定義関数」は有りです。
think49

2019/11/04 14:38 編集

> 自分自身が作り出したものを「自己定義関数」や「ユーザー定義関数」 イメージの問題かもしれませんが、私は「自己定義関数」を「自己書き換えコード」のように読み取れます。 関数 sample が自己(関数 sample)を書き換えるコードです。 https://ja.wikipedia.org/wiki/%E8%87%AA%E5%B7%B1%E6%9B%B8%E3%81%8D%E6%8F%9B%E3%81%88%E3%82%B3%E3%83%BC%E3%83%89 少なくとも、「自己定義関数」は一般的な用語ではありません。 ※他人に説明する際には辞書を引いたり、Google検索する等して「一般的な用語」かを確かめる事をお勧めします。
SugiuraY

2019/11/04 15:02

手元の書籍では該当用語が使用されていたのですが確かにあくまで筆者がそのように読んでいる(読み分けている)だけの可能性もあるので、一般用語か否かは調べてみようと思います。 一つきっかけになりました、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問