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

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

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

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

Q&A

解決済

3回答

3937閲覧

関数の引数が複数ある場合、呼び出し物によって必要な引数と不要な引数がある事が多いですが、引数は順番で、判定するようなので第二引数だけいらない第三だけいらないなど多様なときにどう対処すればよいのでしょう

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

0グッド

0クリップ

投稿2018/03/01 09:10

再利用をする関数の引数が複数ある場合、呼び出し物によって必要な引数と不要な引数がある事が多いですが、引数は順番で、判定するようなので第二引数だけいらない第三だけいらないなど多様なときにどう対処すればよいのでしょうか?

不要な引数の要素も無駄に変数宣言してに取得してあげないとundefinedになって困ります。

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

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

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

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

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

guest

回答3

0

ベストアンサー

※ES6を使える環境前提で書いてみます。

function godFunction({ count = 0, isGod = true, list = [], name = ""} = {} ) {  //引数を使ったいろいろな処理が間にあると仮定 //とりあえず意味はないがcountをそのまま返す return count; } godFunction({ name: 'teratail', count: 1, isGod: true }) godFunction();

https://repl.it/repls/IdealisticTurboScale

引数をオブジェクトで渡してあげれば、引数をどの順番に渡さないといけないかを気にせずに済むようになります。また初期値を設定してあげれば、undefinedも回避出来ます。

とは言え、場合によって使わない引数がよくあるという状況自体が、1つの関数でいろんなことをやろうとし過ぎているのかもしれませんね。関数合成をして、、、(略)

投稿2018/03/01 10:11

編集2018/03/01 10:40
HayatoKamono

総合スコア2415

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

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

退会済みユーザー

退会済みユーザー

2018/03/01 11:06

godFunction({ name: 'teratail', count: 1, isGod: true }) これは始めてみました。 呼び出し元、先の関数の引数の第一引数をオブジェクトにすると、呼び出し先にない値があってもundefinedにならないのですね。 またキーとバリューで渡すので順番も一切気にしなくてもよくなるのですね。 同じ処理は二度かくなとよく言われるので極力関数にした方がいいのかと思っていましたが、むしろそれでわかりずらくなるならむしろ二度書きした方がいいのですね。 関数化は、明らかにシンプルに関数か出来る時だけすればいいのですね。
guest

0

とりあえず参照しない引数なんてダミーでなにか入れておけばよいでしょう
nullでも渡してあげればいいのでは?

javascript

1function test(){ 2 var arg=arguments; 3 console.log(arg[0]||null); 4 console.log(arg[2]||null); 5} 6test(100,null,200); 7//出力:100,200 8test(100); 9//出力:100,null 10

投稿2018/03/01 09:21

編集2018/03/01 09:24
yambejp

総合スコア114837

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

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

退会済みユーザー

退会済みユーザー

2018/03/01 10:27

引数にnullを入れることが出来るのですね。これは思いつきませんでした
guest

0

今すぐ出来る解決手段の1つが引数をオブジェクト1個にする方法です。
一見あり得ない程ダサいですが、ES6でコードを読めばすぐ分かるようになりましたからね。

JavaScript

1var fn = ({name, type, code}) => { 2 console.log(name, type, code); 3} 4console.log(fn({ 5 name: "hoge", 6 type: "request", 7 code: 200, 8})); // "hoge", "request", 200 9// プロパティが足りなくても安心 10console.log(fn({name: "piko"})); // "piko" undefined undefined

別の手段として関数型プログラミングの考えかたから一部輸入してくる方法があります。
カリー化や部分適用と呼ばれる方法です。

「部分適用」の概念が分かりやすいのでこちらを先にやりましょうか。
このfn2やfn3に該当するのが部分適用です。

大げさに「部分適用」みたいなテクニック付けやがって…単純過ぎるだろという怒られが発生しそうですが、
確かに引数1個を要求するけど、2個目や3個目にちゃんと格納されることが確認できます。

JavaScript

1var fn = (val1, val2, val3) => { 2 if (val1 != null && !isValid(val1)) return false; 3 if (val2 != null && !isValid(val2)) return false; 4 if (val3 != null && !isValid(val3)) return false; 5 return true; 6} 7var fn2 = val2 => fn(null, val2, null); 8var fn3 = val3 => fn(null, null, val3);

他にもJavaScriptならではの機能を使って、こんな書き方でも束縛出来ます。

javaScript

1var fn2 = fn.bind(null, null); 2var fn3 = fn.bind(null, null, null);

カリー化はちょっと大変です。
例えば3個の引数を要求する関数の場合、
合計3個の引数が届くまで引数を要求する関数を返し続ける関数のことです。

分かりにくいので、簡単なコードにしてみました。

JavaScript

1// 普通の関数 2var add = (a, b) => a + b 3console.log(add(2, 3)); // 5 4 5// カリー化 6var curried_add = a => b => a + b 7console.log(curried_add(2)(3)); // 5

しかし、このカリー化したadd関数は正当なカリー化ではありません。
上の例では引数1個ずつ渡して発火させましたが、
本来は引数2個でも発火すべきだからです。

JavaScript

1var add = a => b => a + b 2console.log(add(2)(3)); // 5 <- これはまぁその通り 3console.log(add(2, 3)); // (b => a + b) <- 2個目の引数が無視されてる

これ両対応させるの無理じゃね?
そこでちょっと関数を改造します。

JavaScriptの関数は.lengthプロパティが存在し、
関数が求めている引数の数を取り出せます。
これを利用して引数が要求数に満ちるまで実行を遅延させる関数を実装することで解決させます。

JavaScript

1var add = (a, b) => a + b; 2console.log(add.length); // 2

JavaScript

1// 書き方キモいけど許して!ごめんね! 2var curry = (fn, ...savings) => 3 savings.length >= fn.length 4 ? fn.apply(null, savings) 5 : (...args) => { 6 const its = [...savings, ...args]; 7 return its.length >= fn.length 8 ? fn.apply(null, its) 9 : curry(fn, ...its); 10 }; 11var add = curry((a, b) => a + b); 12 13// どっちの書き方もいける 14console.log(add(2)(3)); // 5 15console.log(add(3, 4)); // 7 16console.log(add(5, 6, 7)); // 11 <- 多すぎる分は無視 17 18// こんな風に引数1個だけ束縛しておく事も可能 19var add10 = add(10); 20console.log(add10(3)); // 13 21console.log(add10(5)); // 15

毎回このcurryとかいうよく分からんのをコピペして宣言しないといけないのか…
そうではありません。

関数型プログラミングが出来るライブラリのLodashRamda.jsで定義されています。
これらのライブラリを使えば関数の束縛が非常に楽になります。
Ramda.jsが個人的にはオススメなんですが、Lodashは既に人気があり、多くのプロジェクトが採用しているので、すんなり導入出来るんじゃないでしょうか?

少し長くなりましたが以上です

投稿2018/03/01 11:09

編集2018/03/01 11:12
miyabi-sun

総合スコア21158

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問