从JavaScript函数返回`undefined`或`null`更好吗?


98

我有一个编写的函数,基本上看起来像这样:

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没有回答我的问题...谷歌也没有:\

这样的问题-太宽泛了,我想在这里解决。


1
这个问题不是答案吗?
warkentien2 2016年

8
我认为return null。留给undefinedJavaScript本身。但是,没有“更好”的功能,因此这是一个见解。
菲利克斯·克林

@ warkentien2谢谢,这很有帮助-但对于从getter函数返回的约定,我仍然不清楚。
杰里米·伊格哈特

1
我读null为“您要的东西没有适当的价值”和undefined“我无法弄清您的需求”。
马蒂

@ warkentien2这个问题和我在答案中链接的那个问题有关,但是两者似乎都在问它们之间有什么区别,而不是在何时使用一个或另一个作为返回值。
chiliNUT

Answers:


37

我会争辩说,没有最好的方法,甚至标准函数有时也会选择其中一个。

例如:

  • [[原型]]

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

  • Object.getOwnPropertyDescriptor

    期望返回一个属性描述符,即一个描述属性的对象(例如,值,可写性,可枚举性和可配置性)。但是,该属性可能不存在。在这种情况下,使用表示“没有这样的属性” undefined

  • document.getElementById

    期望返回具有给定ID的元素。但是,可能没有具有该ID的元素。在这种情况下,使用表示“没有这样的元素” null

因此,只需选择您喜欢的或认为对您的特定情况更有意义的东西即可。


3
读这,我决定建议void 0对这个答案的未来观众的技术。我还添加了一些代码来尝试使您的观点更加清楚。谢谢您的回答!
杰里米·伊格哈特

114

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

根据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?


1
是的,未定义是未为变量分配值时使用的值。为什么这恰恰意味着您不应该在函数中返回undefined呢?
Oriol

1
在我看来,@ Oriol是因为void函数返回的是undefined,这是该类型函数的保留值,因此在处理函数的返回值时,null告诉我它决定返回null,而undefined告诉我它要么决定返回未定义,要么决定不返回任何东西,但是我不确定到底是哪个。此外,如果我正在这样做var x=someFunc();,则我有意分配xa值,并且宁愿它不通过任何表明未(或可能尚未)分配值的测试。Just imho
chiliNUT16年

这应该是公认的答案。这就是规范中预期使用的方式
Zinc

1
我没有那样看。我读为:如果您定义一个变量但不初始化它,则它将具有未定义的初始值。程序员应使用Null表示变量为空。恕我直言,未定义的IMHO绝不应该由程序员分配给变量,而是由js引擎使用。术语“对象”值具有误导性,因为在JS中,甚至由于自动装箱,大多数图元在很大程度上也像对象一样运行
chiliNUT

1
是的,这很有意义。公平地说,null只要您坚持使用一个,但我不介意在一个之上使用一个(尽管我更习惯于),但是使用2个值来表示缺少值(无论“类型”如何)总是令人困惑
Sergio Rosas

39

我将以我个人的见解在两种方法之间进行选择。

我的简单问题是:是否可以将给定另一个输入/状态/上下文的值定义为某些值?

如果答案为是,则使用nullelse使用undefined。更一般而言,任何返回对象的函数都应null在目标对象不存在时返回。因为给定另一个输入/状态/上下文,它可能存在。

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

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


1
这对我来说是如此真实。当像函数式程序员一样思考时null,应返回IMO纯函数,而应返回具有副作用undefined的函数。
杰克

4

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 === bundefined。区别在于,您保存了1条语句执行。


@Oriol我的意思是,undefined不必分配。所有声明的没有值的变量都已经存在undefined
choz

@choz&@Oriol-如之前@chiliNUT所述:“请注意,没有指定返回值的函数会隐式返回undefined。” -这是正确的,因为(function(){ /* code */ })()在控制台中返回null。
杰里米·伊格哈特

@JeremyIglehart该代码实际上不返回任何内容。除此之外,它还提供undefined了我的chrome和firefox控制台。
choz

好吧,我不明白你的意思。是的,如果您未明确返回任何内容,则将隐式返回undefined。但是那为什么重要呢?
Oriol

1
@Oriol,我想@choz想要说的是(其他一些人也提到了这个问题),如果我想返回undefined而其他东西没有更早返回,则不需要-因为该函数的默认行为是您不返回任何内容就是返回未定义的内容-他们只是说这是不需要的。进一步...我喜欢您不得不说的关于返回空值的内置getter函数的内容。请发表您对此的回答,我会接受的。
杰里米·伊格哈特

3

取决于您需要如何使用返回值。

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

typeof undefined返回undefined


我个人通常使用null。

4
“该对象的值未定义”不,不是,它不是对象,它为Null。typeof不一定返回值的真实数据类型,它具有将数据类型映射到标签并返回相应标签的映射。
菲利克斯·克林

不要相信typeof,尽管它的名字叫它不告诉值的类型。
Oriol

2

这是一个undefined比以下例子更有意义的示例null

我使用包装函数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中有效,而在JSONundefined中无效。


我知道您在这里做什么-我不能说您错了-因为从某种意义上说,我认为您可以在这里这样做,这很好。我有一个更好的方式来执行此操作,我更喜欢这种方式,因为在此之后我要执行“验证”步骤。我觉得这将验证与返回值混合在一起。这是我的工作:let getStringOrJSON = value => { try { value = JSON.parse(value); } catch(e) { return value; } return value; };。现在,我确定这两种回报方式可能会有所不同,并且可能不会赢得JS高尔夫比赛。有用。
杰里米·伊格哈特

1

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

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

我之所以这样使用,主要是因为:

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

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


1

我认为使用什么是值得商bat的。我更喜欢语义上尽可能准确的代码,因此我认为undefined在这种情况下是合适的。

我认为null赋值的含义是“变量设置为空”。这与undefined“这个东西根本不存在”的意思相反。

正如先前的回答所指出的那样,退货undefined有问题,是否困扰您完全取决于您。这不会打扰我。


2
但是document.getElementById('iDoNotExist')返回null,即使含义更接近于“这个东西根本不存在”。如果使用标准方法,为什么不执行OP?
Oriol

@Oriol我实际上最喜欢您的推理。请发布对此效果的答案,我会接受的。(如果需要,我甚至可以添加一些编辑内容)
杰里米·伊格哈特

Yah @Oriol,这就是为什么我什至在Q / A网站上都喜欢辩论的原因。获得反例确实非常好。而且您提供了一个不错的产品。
Ryan Laboucane

1

我认为在这种情况下,null应该退货。

如果从理论计算机科学的角度考虑问题,则使用undefined来表示非终止/不可计算性(即,通常编写x部分函数 的undefined点的占位符)。ff(x) = ⊥

getNextCard但是似乎可以计算下一张卡(如果存在),并且还可以计算是否没有下一张卡。换句话说,该函数是合计的,因为它会为每个输入终止。

话虽如此,但需要一个特殊的值来表示终止而没有有意义的结果(即“没有卡我可以退回此输入”),而这对我来说则null不是undefined


笔记:

您还可以在其他一些类型化语言中看到对该参数的某种支持,其中使用选项类型(有时也称为nullable type)来表示没有有意义结果的终止。例如,也许是在Haskell中

另一方面,我们当然不知道undefinedJavaScript到底意味着什么。因此,与undefined的类比有点持久。而且,由于我们始终希望使用全部功能,因此相当于说“undefined从功能中永远不会返回”。这似乎有点严格,因为它将限制对undefined尚未设置的属性/变量的使用。

最后,我个人的喜好是永远不要返回undefined我可以返回的地方,null并且我还会争辩说这是更好的编码约定(因为除其他外,x !== null它比短typeof x !== 'undefined')。


-1

根据我的经验,我个人的看法是如果您不想使代码崩溃,则不要使用undefined和null。至少我个人会避免这样做。Javascript中有很多函数都返回undefined,好了,我们必须使用它。但是,当您设计代码时,请不要使用它。务必始终"false"至少返回一些内容。例如,如果您有一个数组并在其上进行映射。返回[undefined, undefined.....]或公正不好undefined。如果保留原始数组的类型更好。例:

 const mapper:Map <string[],boolean[]>  
['i', 'dont', 'use', 'null or undefined'] -> [false, true, false, true, false]
or ['', dont, '', '', use] 
or al the stuff above and then filter(v => v)
that will keep all undefined and null out

那是主意。我一直在努力避免这种情况。因为nullundefined可能很容易使您的代码崩溃

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.