Até onde vi, os parâmetros default não tem otimização, já que são avaliados sempre que a função é chamada. Ex:
function f() {
console.log('chamando f');
return 42;
}
function g(a = f()) {
console.log('g -> a=', a);
}
function h(a) {
a ||= f();
console.log('h -> a=', a);
}
var n = 3;
console.log('chamando g várias vezes');
for (var i = 0; i < n; i++) {
g();
}
console.log('chamando h várias vezes');
for (var i = 0; i < n; i++) {
h();
}
Saída:
chamando g várias vezes
chamando f
g -> a= 42
chamando f
g -> a= 42
chamando f
g -> a= 42
chamando h várias vezes
chamando f
h -> a= 42
chamando f
h -> a= 42
chamando f
h -> a= 42
Repare que f()
sempre é chamada em todas as invocações de ambas as funções g
e h
.
Creio que o ganho do parâmetro default é deixar mais claro na própria lista de parâmetros que eles possuem um valor default (em vez de precisar entrar no código da função pra ver isso).
Mas tem uma diferença importante, se você passar null
ou undefined
para as funções.
Por exemplo, se tivermos:
function f(x = 1) {
return x;
}
function g(x) {
x ||= 1;
return x;
}
Se chamarmos f()
e g()
, o resultado é 1
em ambas. Se chamar f(2)
e g(2)
, o resultado é 2
, e até aí ok.
Mas se passarmos null
ou undefined
:
for (const value of [null, undefined]) {
console.log(`${value} -> f=${f(value)} g=${g(value)}`);
}
f(null)
retorna null
, pois ele entende que foi passado um argumento. Já se chamarmos f(undefined)
, ele entende que o argumento não foi passado e seta o valor para 1
. Já g
retorna 1
em ambos os casos, pois o operador ||
considera tanto null
quanto undefined
como "falso", e aí ele seta o valor para 1
.
Por isso a saída é:
null -> f=null g=1
undefined -> f=1 g=1