Python ではデフォルト引数を与えると関数の宣言時に評価されるので、宣言後にデフォルト引数として与えられている変数を変えたとしても処理は変わらない。他方で JavaScript では変えられてしまう=副作用がある。
グローバル変数をデフォルト引数に設定する
Python
default_greeting = "Hello"
def message(message_1=default_greeting, message_2="World"):
print(f"{message_1} {message_2}")
default_greeting = "こんにちは"
message()
得られる結果は Hello World になる。
JavaScript
let defaultGreeting = "Hello";
function sayHello(greeting = defaultGreeting, target = "World") {
console.log(`${greeting} ${target}`);
}
defaultGreeting = "こんにちは";
sayHello();
得られる結果は こんにちは World になる。
デフォルト引数を配列にする
Python
def function(number, default_arg_list=[]):
default_arg_list.append(number)
return default_arg_list
print(function(1))
print(function(2, [3, 4]))
print(function(3))
print(function(4, [5, 6]))
print(function(5))
この結果は以下が得られる。
[1]
[3, 4, 2]
[1, 3]
[5, 6, 4]
[1, 3, 5]
つまり、 default_arg_list は保持され続けている。
JavaScript
function addNumberToDefaultArray(number, defaultArgArray = []) {
defaultArgArray.push(number);
return defaultArgArray;
}
console.log(addNumberToDefaultArray(1));
console.log(addNumberToDefaultArray(2, [3, 4]));
console.log(addNumberToDefaultArray(3));
console.log(addNumberToDefaultArray(4, [5, 6]));
console.log(addNumberToDefaultArray(5));
得られる結果は以下である。
[ 1 ]
[ 3, 4, 2 ]
[ 3 ]
[ 5, 6, 4 ]
[ 5 ]
つまり、 defaultArgArray は実行するたびに新しい配列が作られている。
わかること
Python の場合は関数の宣言時に、デフォルト引数に与えるデータが決定され、それが保持される。プリミティブなデータであればそのものが、参照であれば参照が保持される。
JavaScript の場合は関数の宣言後でも、デフォルト引数にグローバル変数が与えられればそれを参照する。参照型のものも、毎度新しく参照が作られる。