我们可以只使用“if (a === undefined)”来处理 ES6 之前的 JavaScript 中的默认参数值吗

Can we just use "if (a === undefined)" to handle default parameter values in JavaScript before ES6?

本文关键字:ES6 处理 JavaScript 参数 默认 if 我们 undefined      更新时间:2023-09-26

在 ES6 中,我们可以使用

function f (x, y = 7, z = 42) {
    return x + y + z
}
console.log(f(1));

Babel 和 Traceur 都以这种方式将其转换为类似的 ES5 代码:

"use strict";
function f(x) {
    var y = arguments.length <= 1 || arguments[1] === undefined ? 7 : arguments[1];
    var z = arguments.length <= 2 || arguments[2] === undefined ? 42 : arguments[2];
    return x + y + z;
}
console.log(f(1));

我们不是真的可以处理它吗,就像 http://es6-features.org/#DefaultParameterValues 一样:

function f (x, y, z) {
    if (y === undefined)
        y = 7;
    if (z === undefined)
        z = 42;
    return x + y + z;
}
console.log(f(1));

甚至Mozilla的网站也使用类似的东西:

var b = typeof b !== 'undefined' ?  b : 1;

或关于 SO 用途的标准答案:

function foo(a, b)
 {
   a = typeof a !== 'undefined' ? a : 42;
   b = typeof b !== 'undefined' ? b : 'default_b';
   ...
 }

我们为什么不使用简短的

if (y === undefined)
        y = 7;

有什么细微的区别吗?

(在全局范围内确实如此,我们不能只说a === undefined如果从未声明a(它会引发错误)。但是在函数内部,我们可以只使用 a === undefined,因为a已经列在参数列表中。但是,Babel 和 Traceur 都没有在参数列表中列出默认参数。

我们可以只使用 if (a === undefined) 来处理 ES6 之前的 JavaScript 中的默认参数值吗?

是的,你可以这样做,这完全没问题。

但你是对的,有一个微妙的区别(或两个):

  • f.length是 ExpectArgumentCount,即第一个休息或初始化之前的参数数。
  • function f( a=b, b=0 )变量b具有时间盲区,不得由a的初始化器使用。

像 Babel 这样的转译器试图尽可能接近地复制这样的东西,这就是为什么它们使用 arguments 对象并在函数体中声明变量。顺便说一句,Babel 无法正确处理function f(a=0, b)

是的,你可以,这就是我一直这样做的方式(大约 15 年),它永远不会出错。通过将其添加到参数列表中,您始终可以将其作为声明的变量访问,而且我从未遇到过无法处理它的浏览器。

不过,我更喜欢使用typeof varname == 'undefined',因为我过去在一些晦涩的浏览器中遇到过一些=== undefined问题。

我总是倾向于尽可能远离参数属性。