从 javascript 函数中返回“未定义”或“空”是否更好?

我写了一个这样的函数:

function getNextCard(searchTerms) {
// Setup Some Variables


// Do a bunch of logic to pick the next card based on termed passed through what I'll call here as 'searchTerms' all of this logic is omitted because it's not important for my question.
// ...


// If we find a next card to give, than give it
if (nextCardFound)
return nextCardFound;


// Otherwise - I'm returning undefined
return undefined;
}

问: 在这里返回“ null”是否更好?

我可以通过任何我想回来-显然... 我只是不知道什么是最好的东西使用。

调用此函数的代码知道如何处理未定义的情况(除非出现严重错误,否则实际上永远不会发生这种情况)

我问这个问题的原因是,我听到一些类似“不要赋予未定义的变量”或类似的东西-这将使调试更加困难。所以,我可以看到 null被传回这一事实告诉我返回正在工作——但基本上功能类似于 undefined


文件:

Mozilla Docs 没有回答我的问题... ... 谷歌也没有回答:

这个 SO 问题对于我在这里试图弄明白的东西来说太宽泛了。

112829 次浏览

取决于您需要如何处理返回的值。

Typeof null 返回一个对象。该对象的值为未定义

Typeof 未定义的返回值未定义

第一个答案是正确的。它们在理论上有不同的含义。然而,我们并不总是清楚应该选择哪一个。

我倾向于在我的开发中使用 null,尽管我认为这完全是主观的东西。

我这么说主要是因为:

  1. 未定义的变量在旧的浏览器中可能会被覆盖,所以返回它有点复杂。同样的问题迫使您在获得函数结果时使用 typeof var === 'undefined'链接

  2. 其他语言倾向于广泛使用 null,很多语言甚至没有未定义(例如 php)。当我在语言之间快速交换时,这给了我某种一致性。

未定义通常指的是尚未分配值(尚未)的事物。Null 指的是绝对没有价值的东西。在这种情况下,我建议返回一个 null。注意,没有指定返回值的函数隐式返回未定义的值。

来自 ECMAScript2015规范

4.3.10未定义值

未为变量赋值时使用的基元值

4.3.12空值

基元值,该基元值表示 故意没有任何对象价值

Http://www.ecma-international.org/ecma-262/6.0/#sec-terms-and-definitions-undefined-type

进一步阅读:

何时在 JavaScript 中使用 null 或未定义?

我认为使用什么是非常有争议的。我更喜欢语义尽可能准确的代码,所以我认为 undefined在这种情况下是适当的。

我认为 null的赋值意味着“一个设置为零的变量”。这与 undefined的意思相反,undefined的意思是“这个东西根本不存在”

正如前面的答案所指出的,返回 undefined存在问题,这完全取决于您是否对此感到困扰。我不会介意的。

undefined不是您应该分配给的内容。您可能需要考虑返回除 undefined之外的其他内容。在您的示例中,即使根本不返回任何内容,结果也将是 undefined。所以,我建议用 null代替。

考虑一下这个样本,

function getSomething() {
// .. do something
return undefined;
}


function doSomething() {
// .. I'm not gonna return anything.
}


var a = getSomething();
var b = doSomething();

以上示例的结果是 a === b,即 undefined。不同之处在于您保存了1条语句的执行。

我认为没有最好的方法,即使是标准函数有时也会选择其中一种。

例如:

  • [原型]

    普通对象有一个[[ Prototype ]]内部槽,它决定它们从哪个其他对象继承。当然,必须有一种方法可以说明一个对象不是从任何其他对象继承而来的。在这种情况下,使用 null表示“没有这样的对象”。

  • Object.getOwnPropertyDescriptor

    它期望返回一个属性描述符,即一个描述属性的对象(例如,值、可写性、可枚举性和可配置性)。但是,该属性可能不存在。在本例中,“ there is no such property”使用 undefined表示。

  • document.getElementById

    期望它返回具有给定 ID 的元素。但是,可能没有具有该 ID 的元素。在本例中,“ there is no such element”使用 null表示。

所以,只要选择你喜欢的或者认为对你的具体情况更有意义的任何东西。

我会告诉你我个人在这两者之间的选择。

我的简单问题是: 如果给定另一个输入/状态/上下文,这个值是否可以定义为某个东西?

如果答案是肯定的,那么使用 null,否则使用 undefined。更一般地说,当预期对象不存在时,任何返回对象的函数都应该返回 null。因为它可能存在于另一个输入/状态/上下文中。

null表示给定输入/状态/上下文的 没有价值。它隐含地意味着值本身的 概念存在于应用程序的上下文中,但可能不存在。 在您的示例中,存在下一张卡片的概念,但是卡片本身可能不存在。应使用 null

undefined隐式地表示应用程序上下文中该值的 没有意义。例如,如果我使用给定的一组属性操作 user对象,并尝试访问属性 pikatchu。这个属性的值应该设置为 undefined,因为在我的上下文中,拥有这样的属性没有任何意义。

下面是一个 undefinednull更有意义的例子:

我使用了一个 JSON.parse的包装函式,它将异常转换为 undefined:

// parses s as JSON if possible and returns undefined otherwise
// return undefined iff s is not a string or not parseable as JSON; undefined is not a valid JSON value https://stackoverflow.com/a/14946821/524504
function JSON_parse_or_undefined(s) {
if ("string" !== typeof s) return undefined


try {
const p = JSON.parse(s)
return p
} catch (x){}


return undefined
}

请注意,null在 JSON 中是有效的,而 undefined则不是。

我认为在这种情况下,应该返回 null

如果你从理论计算机科学的角度来考虑这个问题,那么 未定义被用来表示 不终止合约/不可计算性(即 部分函数 f的未定义点 x的占位符,它通常被写成 f(x) = ⊥)。

然而,getNextCard似乎能够计算下一张卡(如果存在的话) ,也能够计算没有下一张卡的情况。换句话说,该函数是 总数,因为它对每个输入都终止。

也就是说,一个 特殊价值信令终止没有有意义的结果(即“没有卡,我可以返回这个输入”)是必需的,这对我来说是 null而不是 undefined


备注:

您可以在其他一些类型化语言中看到对此参数的一些支持,在这些语言中,没有有意义结果的终止使用 选项类型(有时也称为 可空类型)表示。这方面的一个例子是 Haskell中的 也许吧

另一方面,我们当然不知道在 JavaScript 中 undefined的真正含义。因此,与 未定义的类比有点牵强。此外,由于我们总是希望使用总函数,这相当于说“永远不要从函数返回 undefined”。这似乎有点严格,因为它会将 undefined的使用限制到尚未设置的属性/变量。

最后,我个人的偏好是永远不返回 undefined,在这里我可以返回 null,我还要说,这是更好的编码约定(因为在其他事情中,x !== nulltypeof x !== 'undefined'短)。