Posted at

JavaScript で通常引数の関数呼び出しと分割代入による名前付き引数呼び出しで関数オーバーロードする

JavaScriptでは引数が固定されないので、関数オーバーロードは引数の内容をみて自分で処理わけしたりします。

で、既存の関数呼び出しと、名前付き引数での関数呼び出しをどちらも行えるようにします。

コードで示すとこんな感じにしたいということ。

console.log(testAdd(10, 20));  // 30 と表示

console.log(testAdd({ valueA: 10, valueB: 20 })); // 30 と表示

どちらも同じ testAdd 関数ですが、通常の引数が2つの呼び出しと、名前付き引数呼び出しを共存させます。

これをどうやって実現させるかというと、下記のように行います。

const isObject = function(value) {

if (
Object.prototype.toString.call(value) === '[object Object]' &&
value !== null &&
typeof value !== 'undefined'
) {
return true;
}
return false;
};

const isArgsDestAssign = args => {
return args.length === 1 && isObject(args[0]);
};

const argsAssign = (argsValue, valueNames) => {
const args = Array.isArray(argsValue) ? argsValue : Array.from(argsValue);
if (isArgsDestAssign(args)) {
return args[0];
}
const result = {};
valueNames.split(',').forEach((valueName, index) => {
result[valueName.trim()] = argsValue[index];
});
return result;
};

// -----

const testAdd1 = function() {
const { valueA, valueB } = argsAssign(arguments, 'valueA, valueB');
return valueA + valueB;
};

const testAdd2 = (...args) => {
const { valueA, valueB } = argsAssign(args, 'valueA, valueB');
return valueA + valueB;
};

testAdd1 は、関数式(関数宣言も同じ)での、testAdd の実装。

arguments を使っています。

testAdd2 は、アロー関数での、testAdd の実装。

残余引数を使っています。

引数が1つで、中身がオブジェクトの場合と、

それ以外のときとで、変数に代入する前で、処理分岐して処理を行っています。

もっと、引数の型チェックしたい場合は、こちら参考に。よろしくです。

型チェックは TypeScript や Flow じゃなくて JavaScript にやらせる。 - Qiita

https://qiita.com/standard-software/items/0b2617062b2e4c7f1abb