引数・可変長引数 (arguments)・値渡し/参照渡し・戻り値
デフォルト引数 ・可変長引数
引数・可変長引数 (arguments)・値渡し/参照渡し・戻り値
メモ
- EcmaScript 2015 (6) 以降では、明示的な 可変長引数 が使用可能
- 関数定義 と 関数呼び出しの引数の数が不一致でも関数呼び出し可能 ( 例 参照)
- 不足引数:undefined または デフォルト引数 の値
- 過剰引数:下記 arguments【引数リスト】参照
- 関数が呼び出されると自動的に arguments 【引数リスト】を作成
- 配列風オブジェクト
- 可変長引数として使用 ( 例 参照)
- アロー関数 (=>) 内では使用不可
arguments 説明 備考 arguments[0~] 各引数 strict モードでは代入不可 arguments.callee 実行中の関数 strict モードでは使用不可 (TypeError例外) arguments.caller 呼び出した関数 (実装依存) strict モードでは使用不可 (TypeError例外)
参考:Function.caller【呼び出した関数】 プロパティarguments.length 呼び出し時の引数の数 引数の定義数はFunction.length【引数の定義数】プロパティ - プリミティブ型は値渡し、オブジェクト型は参照渡し (厳密には共有渡し) ( 例 参照)
- 戻り値が未指定の場合、 戻り値は undefined【未定義】 ( 例 参照)
【引数の過不足】
function func(x, y) {
console.log(x, y);
}
// 以下全て呼び出し可能
func(1, 2); // 出力:1 2
func(1); // 出力:1 undefined
func(); // 出力:undefined undefined
func(1, 2, 3); // 出力:1 2
【arguments(引数リスト)】
function func(x, y) {
console.log("arguments.callee = " + arguments.callee);
console.log("arguments.caller = " + arguments.caller);
console.log("arguments.length = " + arguments.length);
for (var i = 0; i < arguments.length; i++) {
console.log("arguments[" + i + "] = " + arguments[i]);
}
console.log("func.length = " + func.length);
console.log("func.caller = " + func.caller);
}
function func2(x, y) {
func(x, y);
}
func(1, 2);
// 出力:arguments.callee = function func(…
// 出力:arguments.caller = 実装依存
// 出力:arguments.length = 2
// 出力:arguments[0] = 1
// 出力:arguments[1] = 2
// 出力:func.length = 2
// 出力:func.caller = null
func(3, 4, 5); // 関数定義より多い引数
// 出力:arguments.callee = function func(…
// 出力:arguments.caller = 実装依存
// 出力:arguments.length = 3
// 出力:arguments[0] = 3
// 出力:arguments[1] = 4
// 出力:arguments[2] = 5
// 出力:func.length = 2
// 出力:func.caller = null
func2(6, 7);
// 出力:arguments.callee = function func(…
// 出力:arguments.caller = 実装依存
// 出力:arguments.length = 2
// 出力:arguments[0] = 6
// 出力:arguments[1] = 7
// 出力:func.length = 2
// 出力:func.caller = function func2(…
【値渡し/参照渡し (共有渡し)】
function func(bool, num, str, array1, array2, date1, date2, obj1, obj2) {
console.log(bool);
console.log(num);
console.log(str);
console.log(array1);
console.log(array2);
console.log(date1.toISOString());
console.log(date2.toISOString());
console.log(obj1);
console.log(obj2);
bool = false
num = 100;
str = "変更後";
array1[0] = 10; // 変更
array2 = [10, 20, 30]; // 新規作成
date1.setUTCFullYear(2011, (12 - 1), 13); // 変更
date2 = new Date("2011-12-13T14:15Z"); // 新規作成
obj1.x = 10;
obj2 = {x:1, y:2, z:3};
}
var bool = true;
var num = 1;
var str = "変更前";
var array1 = [1, 2, 3];
var array2 = [1, 2, 3];
var date1 = new Date("2001-02-03T04:05Z");
var date2 = new Date("2001-02-03T04:05Z");
var obj1 = {x:1, y:2};
var obj2 = {x:1, y:2};
func(bool, num, str, array1, array2, date1, date2, obj1, obj2);
// 出力:true
// 出力:1
// 出力:変更前
// 出力:[1, 2, 3]
// 出力:[1, 2, 3]
// 出力:2001-02-03T04:05:00.000Z
// 出力:2001-02-03T04:05:00.000Z
// 出力:Object {x: 1, y: 2}
// 出力:Object {x: 1, y: 2}
func(bool, num, str, array1, array2, date1, date2, obj1, obj2);
// 出力:true
// 出力:1
// 出力:変更前
// 出力:[10, 2, 3]
// 出力:[1, 2, 3]
// 出力:2011-12-13T04:05:00.000Z
// 出力:2001-02-03T04:05:00.000Z
// 出力:Object {x: 10, y: 2}
// 出力:Object {x: 1, y: 2}
【未指定の戻り値】
function func1() {
}
function func2() {
return;
}
console.log(func1()); // 出力:undefined
console.log(func2()); // 出力:undefined
関連
- ECMAScript 5.1 (英語)
- ECMAScript 2015 (6) (英語)
- ECMAScript 2016 (7) (英語)
デフォルト引数 ・可変長引数
メモ
- デフォルト引数
- 引数の後に省略時の値を記述 (例:p1 = 1, p2 = 2)
- デフォルト値として前の引数を参照可能 (例:p1 = 1, p2 = p1 + 1)
- 可変長引数
- 明示的な記述方法 (例:p1, ...pN)
- 指定引数は、Array【配列】 (argumentsは疑似配列)
- 指定引数は、未指定部分の引数配列、可変長引数 (arguments)は全ての引数を含む
【コードによるデフォルト引数】
/**
* RGB値 取得
* @param {number} [r=255] 赤色
* @param {number} [g=255] 緑色
* @param {number} [b=255] 青色
* @return {number} RGB値
*/
function rgbA(r, g, b) {
r = (r === undefined) ? 255 : r;
g = (g === undefined) ? 255 : g;
b = (b === undefined) ? 255 : b;
return r * 0x10000 + g * 0x100 + b;
}
console.log(rgbA().toString(16)); // 出力:ffffff
console.log(rgbA(64).toString(16)); // 出力:40ffff
console.log(rgbA(64, 128).toString(16)); // 出力:4080ff
console.log(rgbA(64, 128, 192).toString(16)); // 出力:4080c0
【デフォルト引数 】
/**
* RGB値 取得
* @param {number=} r 赤色
* @param {number=} g 緑色
* @param {number=} b 青色
* @return {number} RGB値
*/
function rgbB(r = 255, g = 255, b = 255) {
return r * 0x10000 + g * 0x100 + b;
}
console.log(rgbB().toString(16)); // 出力:ffffff
console.log(rgbB(64).toString(16)); // 出力:40ffff
console.log(rgbB(64, 128).toString(16)); // 出力:4080ff
console.log(rgbB(64, 128, 192).toString(16)); // 出力:4080c0
【引数をデフォルト引数に指定】
/**
* 合計値 取得
* @param {number} p1 パラメータ1
* @param {number} [p2=p1+1] パラメータ2
* @param {number} [p3=p2+1] パラメータ3
* @return {number} 合計値
*/
function sumA(p1, p2 = p1 + 1, p3 = p2 + 1) {
console.log("sumA:", p1, p2, p3);
return p1 + p2 + p3;
}
console.log(sumA(1));
// 出力:sumA: 1 2 3
// 出力:6
console.log(sumA(2));
// 出力:sumA: 2 3 4
// 出力:9
console.log(sumA(1, 2));
// 出力:sumA: 1 2 3
// 出力:6
console.log(sumA(1, 3));
// 出力:sumA: 1 3 4
// 出力:8
console.log(sumA(1, 2, 3));
// 出力:sumA: 1 2 3
// 出力:6
console.log(sumA(2, 4, 6));
// 出力:sumA: 2 4 6
// 出力:12
【可変長引数 (arguments)】
/**
* 合計値 取得
* @param {...number} p1
* @return {number} 合計値
*/
function sumB(p1) {
var answer = 0;
for (var i = 0; i < arguments.length; i++) {
answer += arguments[i];
}
return answer;
}
console.log(sumB(1, 2, 3)); // 出力:6
console.log(sumB(1, 2, 3, 4, 5)); // 出力:15
【可変長引数 】
/**
* 合計値 取得
* @param {number} p1
* @param {...number} pN
* @return {number} 合計値
*/
function sumC(p1, ...pN) {
console.log("sumC:arguments.length = " + arguments.length);
console.log("sumC:pN.length = " + pN.length);
var answer = p1;
for (var i = 0; i < pN.length; i++) {
answer += pN[i];
}
return answer;
}
console.log(sumC(1, 2, 3));
// 出力:sumC:arguments.length = 3
// 出力:sumC:pN.length = 2
// 出力:6
console.log(sumC(1, 2, 3, 4, 5));
// 出力:sumC:arguments.length = 5
// 出力:sumC:pN.length = 4
// 出力:15
関連
- ECMAScript 2015 (6) (英語)
- ECMAScript 2016 (7) (英語)