javascriptで下記の様な事は出来るでしょうか。
名前が同じで、引数の数が違う関数です。
javascript
1//合計の計算 2function calcSum(n1, n2){ 3 return n1 + n2; 4} 5 6//合計の計算 7function calcSum(n1, n2, n3){ 8 return n1 + n2 + n3; 9} 10
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
ベストアンサー
残念ながら、JavaScriptで同じ名前の関数を複数宣言することはできません。
ただ、いくつか代替となる手段はあります。
javascript
1// 引数の個数を見分ける 2// 引数の個数で違う動きをする場合におすすめ 3function calcSum1(n1, n2, n3) { 4 if(arguments.length === 2) { 5 // 2個の場合の処理 6 } 7 if(arguments.length === 3) { 8 // 3個の場合の処理 9 } 10} 11 12// 「引数全部処理したい場合」、以下2つのような手もある 13function calcSum2() { 14 var ret = 0; 15 for(var i = 0; i < arguments.length; i++) { 16 ret += arguments[i]; 17 } 18 return ret; 19} 20 21// ES6(現状では環境を選ぶ) 22function calcSum3(...args) { 23 // argsは本物の配列 24 return args.reduce((total, current) => total + current, 0); 25}
投稿2017/11/18 08:06
総合スコア145941
0
他回答者の方がもう色々な方法を提示されたので、
私は選択肢の使い分けの目安を示したいと思います。
ご質問のサンプルコードのように、
増えていく引数の型が同じで、処理も同じ、単調な変化の場合は、
配列を引数に取ってループの回数を変えるのが一番シンプルです。
次に、引数が2個だと引き算、3個だと足し算、
のように型は同じでも処理を分ける必要がある場合、
IF文を使って分岐させます。
さらに、数を足すのか、文字列を連結するのか、
という風に引数の型が異なる場合、
別のオブジェクトに同名のメソッドを付ける
(ポリモーフィズム)のがオススメです。
なぜかというと、型が違う場合、別系統のデータだから、
別オブジェクトに分けた方が整理しやすいのです。
とくにIF文がネストするような複雑な場合に威力を発揮します。
なお、方向性は違いますが、引数のパターンが単調な場合、
とくに内部のIF文を分けるためのフラグとして引数を使っている場合、
高階関数と部分適用で分ける関数型的な手法も有力です。
この場合、名前を増やす代わりに、引数を減らして整理します。
同名はひとつの手段で、目的はコードの整理だと思うので、選択肢のひとつです。
投稿2017/11/18 09:55
編集2017/11/18 09:58総合スコア5592
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
別オブジェクトのメソッドにするとか。
JavaScript
1var a = {}; 2var b = {}; 3a.calcSum = function ( n1, n2 ) { 4 return n1 + n2; 5} 6b.calcSum = function ( n1, n2, n3 ) { 7 return n1 + n2 + n3; 8} 9console.log( a.calcSum( 1, 2 ) ); 10console.log( b.calcSum( 1, 2, 3 ) );
投稿2017/11/18 08:14
総合スコア69583
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/11/18 09:04
2017/11/18 09:57
0
多重定義
JavaScriptに多重定義の仕組みはない為、可変引数コード実装時に使われる機構を活用することになります。
多重定義と同様に関数を分割定義したいのならば、多重定義用の関数を一つ用意してやる必要があります。
JavaScript
1function calcSum (n1) { 2 switch(arguments.length) { 3 case 0: 4 throw new Error; 5 case 1: 6 return n1; 7 case 2: 8 return calcSum2(n1, arguments[0]); 9 case 3: 10 return calcSum3(n1, arguments[0], arguments[1]); 11 } 12 13 throw new Error; 14} 15 16function calcSum2 (n1, n2){ 17 return n1 + n2; 18} 19 20function calcSum3 (n1, n2, n3){ 21 return n1 + n2 + n3; 22} 23 24console.log(calcSum(1)); // 1 25console.log(calcSum(1, 2)); // 2 26console.log(calcSum(1, 2, 3)); // 4 27console.log(calcSum(1, 2, 3, 4)); // Error 28console.log(calcSum()); // Error
ここで重要なのは、
JavaScript
1calcSum.length === 1; // true
であり、最低一つの引数を要求する事が明確になっている点です。
arguments
を使って実引数を参照する事で、 Function#length
の値をコントロール出来ます。
なお、ES6 の Rest parameters で同様の実装をするには、次のように書きます。
JavaScript
1function calcSum (n1, ...n) {} 2console.log(calcSum.length); // 1
Re: uer03108 さん
投稿2017/11/18 14:10
編集2017/11/18 14:36総合スコア18189
0
JavaScriptでは同名の関数は1個しか存在出来ません。
関数を定義すると、関数の内部でarguments
変数が利用可能になります。
それでよしなに計算し、if文等で処理を分岐させる仕組みを盛り込むことになります。
参考サイト: arguments - MDN
他にも引数が不足していても、余った引数にUndefinedが格納されるだけでエラーにはなりません。
JavaScript
1function calcSum(a, b, c) { 2 return a + b + c; 3} 4console.log(calcSum(1, 2, 3)); // 6 5console.log(calcSum(1, 2)); // NaN <- ちくしょう! 6 7function calcSum(a, b, c) { 8 a = a || 0; 9 b = b || 0; 10 c = c || 0; 11 return a + b + c; 12} 13console.log(calcSum(1, 2, 3)); // 6 14console.log(calcSum(1, 2)); // 3 15 16// ES2015という新しい書き方では、引数の初期値が宣言出来るようになりました。 17function calcSum(a = 0, b = 0, c = 0) { 18 return a + b + c; 19} 20console.log(calcSum(1, 2)); // 3
おまけ: 単純操作なら配列操作
calcSumというのは複数の数値を全て足すという処理ですね?
例題なんでアレですが、こういう単純処理ならば配列操作でいけますね。
配列を受け取る関数を作って対応できます。
JavaScript
1function calcSum(nums) { 2 return nums.reduce(function(a, b){return a + b}, 0); 3} 4console.log(calcSum([])); // 0 5console.log(calcSum([1])); // 1 6console.log(calcSum([1, 2])); // 3 7console.log(calcSum([1, 2, 3])); // 6 8console.log(calcSum([1, 2, 3, 5, 5])); // 16
argumentsと配列操作を使ってかっこよく仕上げます。
自動的に宣言されるargumentsは配列っぽい変数ですが、配列から継承して作られた存在ではなく、
リスト操作のメソッドを使おうとするとエラーが出ます。
参考サイト: [JavaScript] arguments をサクッと配列に変換する方法
JavaScript
1function calcSum() { 2 var args = Array.prototype.slice.call(arguments); 3 return args.reduce(function(a, b){ return a + b }, 0); 4} 5console.log(calcSum()); // 0 6console.log(calcSum(1)); // 1 7console.log(calcSum(1, 2)); // 3 8console.log(calcSum(1, 2, 3)); // 6 9console.log(calcSum(1, 2, 3, 4)); // 10
おまけのおまけ!: ES2015をフルに使った場合
maisumakun:
babelやNode前提の環境では、(同種の引数を任意個受ける、という状況なら)最後のようにspread引数として宣言しておくのがわかりやすい気もします。
JSも幾つかバージョンがあり、ES2015という新バージョンでは更に強化した記述が可能になりました。
アロー演算子、spread、reduceをフル活用すれば質問文の例題を1行で書けてしまいます。
残念ながらIE11では対応していませんが、他のモダンブラウザ全てとNode.jsでは扱えますので調べてみてください。
IE11に対応する場合、Babelという古いJSのバージョンに戻すソフトを使えば大体動作します。
自動化ツールを組んで、書いたコードをデプロイ前にBabelを通して反映するということが可能です。
JavaScript
1const calcSum = (...nums) => nums.reduce((a, b) => a + b, 0) 2console.log(calcSum()); // 0 3console.log(calcSum(1)); // 1 4console.log(calcSum(1, 2)); // 3 5console.log(calcSum(1, 2, 3)); // 6 6console.log(calcSum(1, 2, 3, 4)); // 10
投稿2017/11/18 09:04
編集2017/11/18 09:28総合スコア21194
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/11/18 09:00
2017/11/18 09:10