什么原因在JavaScript中使用null而不是undefined?

Jim*_*dra 94 javascript null undefined

我已经写了很长时间的JavaScript了,我从来没有理由使用它null.似乎undefined总是更可取,并以编程方式提供相同的目的.用什么实际理由null代替undefined

bbg*_*bbg 81

我真的不知道答案,但根据尼古拉斯C. Zakas,他的书第30页" 专业的JavaScript的Web开发 ":

在定义稍后要保存对象的变量时,建议将变量初始化null为其他任何变量.这样,您可以显式检查该值,null以确定该变量是否已在以后填充了对象引用

  • +1是的,我同意并且我总是试图记住将vars初始化为null.然后我(非常)确定"未定义"意味着发生了灾难.只是imho. (8认同)
  • @Pete - 但它没有告诉你关于"灾难"的事情,那么重点是什么?如果你知道函数遵循约定,那么你只能做出这个假设. (7认同)
  • 另一方面,您还可以使用`var myVar;`初始化变量,并显式检查值`undefined`以确定它是否在以后填充了对象引用.我的观点是,这完全是学术性的 - 你可以用任何一种方式做到这一点,而任何一方面提出建议的人都只是推动他们自己的惯例. (6认同)
  • @GMan - 这是`==`比较(而不是`===`)有意义的唯一地方:`v == null`(或`v == undefined`)将检查null或undefined. (2认同)

B T*_*B T 42

Null和undefined本质上是两个不同的值,意思是相同的东西.唯一的区别是在约定的你如何使用它们系统.正如一些人所提到的,有些人使用null表示"无对象",你有时可能会获得一个对象,而未定义意味着没有预期的对象(或者有错误).我的问题是完全随意,完全没必要.

也就是说,有一个主要的区别 - 未初始化的变量(包括没有传递参数的函数参数等)总是未定义的.

这就是为什么在我的代码中我从不使用null,除非我不控制的东西返回null(例如正则表达式匹配).它的美妙之处在于它将事物简化了很多.我永远不必检查x === undefined || x === null.如果你习惯使用==或简单的东西,如if(x).... 停下来.!x将为空字符串,0,null,NaN评估为true - 即您可能不想要的东西.如果你想编写不太糟糕的javascript,请始终使用triple equals ===并且永远不要使用null(使用undefined代替).它会让你的生活更轻松.

  • 我不同意这一点.Null用于以编程方式定义空的内容.未定义意味着该引用不存在.null值具有对"nothing"的定义引用.如果您正在调用对象的不存在属性,那么您将得到未定义.如果我故意将该属性设为空,那么它必须为null,因此您知道它是故意的.许多JavaScript库都是这样工作的. (114认同)
  • @ com2ghz你所描述的是众多哲学中的一种.许多js库确实以这种方式工作.许多人也不这样做.在javascript中,您可以像在null中一样轻松地在对象或数组中存储显式的未定义值.两者的含义完全和完全依赖于上下文.IE他们意味着你想要他们的意思. (3认同)
  • @com2ghz 所以 JS 是一种可怕的语言,因为它同时具有 null 和 undefined?在所有主要语言中,我可以数出数十种糟糕的语言决策,js 也不例外。我真的从来不需要或不想在我的代码中使用虚假检查,并且总是使用 `===` 或 `!==`。如果您知道如何使用 JS,那么它是一种极具表现力的语言。 (3认同)
  • 对.我刚刚了解到`null` /`undefined`二分法是必要的,因为JS的初始版本没有`hasOwnProperty`或`in`运算符.既然如此,我真的不明白为什么其中一个在ES6或我见过的任何ES7提案中都没有废除. (3认同)
  • 这就是为什么JS是一种可怕的语言。就像您说的那样,许多图书馆都有自己的理念,但是您为一个项目提供了许多图书馆。因此,您遇到了这些库的许多约定。您需要进行几次虚假检查。这不是最后一次将空对象连接到字符串并获得“ null”作为字符串。或传递一个0作为数值,并想知道IF语句为什么要处理,则将t视为假。 (2认同)
  • @Andy我同意,我认为拥有 null *and* undefined *and* 属性包含是一个糟糕的设计选择。理想情况下,只有其中之一存在(即,将属性设置为未定义将意味着 obj 中的“hello”将返回 false)。 (2认同)
  • 当然,虽然他们可以有一个"使用超级"模式,只允许其中一个:) (2认同)
  • @VahagnNikoghosian 这正是我的回答说这取决于您系统中的约定的原因。我同意它们只是可以意味着你想要它们意味着什么的价值观。我会争辩说,它很容易拥有像exports.mySpecialNull1 = {}这样的语义值,您可以将事物与之进行比较 - 这与使用null一样高效,并且具有更多的表达能力。您可以在 javascript 中创建一个完整的枚举,您可以使用它来代替基本的 null vs undefined vs full value。您可以根据需要继续使用 null,但还有更好的选择。 (2认同)
  • 我如何得知NULL就像别人的名字一样。您知道任何人都有名字,但您不知道他/他的名字。未定义是指不存在的内容。 (2认同)

Ale*_*lov 12

undefined是没有概念存在的地方; 它没有类型,并且在该范围之前从未被引用过; null是已知存在的东西,但它没有价值.

  • 你怎么知道是否试图分配一个值,但它失败并且*undefined*被分配了? (3认同)

Rob*_*obG 10

您可以采用此处建议的约定,但实际上没有充分的理由.它的使用不够一致,没有意义.

为了使约定有用,首先必须知道被调用的函数遵循约定.然后,您必须显式测试返回的值并决定要执行的操作.如果未定义,则可以假设被调用函数知道发生了某种错误.但是如果发生错误,并且函数知道它,并且将它发送到更广泛的环境中是有用的,为什么不使用错误对象呢?即抛出错误?

因此,在一天结束时,除了简单环境中的非常小的程序之外,该约定实际上是无用的.


thd*_*oan 10

每个人都有自己的编码方式和他们自己的内部语义,但多年来我发现这是最直观的建议,我给那些提出这个问题的人:当有疑问时,做JavaScript做的事情.

假设您正在处理对象属性,例如jQuery插件的选项......问问自己JavaScript给出了一个尚未定义的属性的价值 - 答案是undefined.所以在这种情况下,我会用'undefined'初始化这些类型的东西,以便与JavaScript保持一致(对于变量,你可以var myVar;代替var myVar = undefined;).

现在让我们说你正在进行DOM操作...... JavaScript为不存在的元素分配了什么价值?答案是null.如果您要创建一个占位符变量,稍后将保存对与DOM相关的元素,文档片段或类似内容的引用,那么这是我将初始化的值.

如果您正在使用JSON,则需要进行特殊情况:对于未定义的属性值,您应该将它们设置为""或者null因为值undefined不被视为正确的JSON格式.

有了这个说法,正如之前的一张海报所表达的那样,如果你发现你在蓝色月亮中使用nullundefined不止一次初始化东西,那么也许你应该重新考虑如何编写你的应用程序.


Mat*_*Way 7

有些人说可以将对象初始化为null. 我只是想指出解构参数默认值不适用于null. 例如:

const test = ({ name } = {}) => {
  console.log(name)
}

test() // logs undefined
test(null) // throws error
Run Code Online (Sandbox Code Playgroud)

这需要在调用函数之前执行null检查,这可能经常发生。


Gov*_*Rai 6

在这一天结束,因为两者nullundefined要挟相同的值(Boolean(undefined) === false && Boolean(null) === false),你可以在技术上使用要么把工作做好。但是,IMO有正确的方法。

  1. 将用法的使用留给undefinedJavaScript编译器。

    undefined用于描述不指向参考的变量。JS编译器会照顾您。在编译时,JS引擎会将所有提升变量的值设置为undefined。当引擎逐步执行代码并获得值时,引擎会将各自的值分配给各自的变量。对于那些没有为其找到值的变量,这些变量将继续保持对原语的引用undefined

  2. 仅当您明确希望将变量的值表示为“无值”时,才使用null。

    如@ com2gz所述:null用于以编程方式定义为空。undefined表示该引用不存在。一个null价值有一个定义的参考,以“无”。如果调用的是对象的不存在属性,则将得到undefined。如果我故意将该属性设为空,则必须为空,null以便您知道它是故意的。

TLDR;不要使用undefined原语。当您声明没有赋值的变量或尝试访问没有引用的对象的属性时,JS编译器会自动为您设置一个值。另一方面,null仅当您有意让变量具有“无值”时,才使用。

我从来没有明确地将任何内容设置为undefined(并且我在与之交互的许多代码库中都没有遇到过)。另外,我很少使用null。我唯一使用的时间null是当我想将函数参数的值表示为没有值时,即:

function printArguments(a,b) {
  console.log(a,b);
}

printArguments(null, " hello") // logs: null hello
Run Code Online (Sandbox Code Playgroud)

  • 这应该是选定的答案 (7认同)
  • 经过多年仅使用“未定义”并假装“空”不存在之后,我想我开始倾向于这样的答案 (7认同)