有什么理由使用null,而不是在JavaScript中定义?

我已经写了很长一段时间的JavaScript,我从来没有理由使用null 。 看来, undefined总是可取的,并以编程方式用于相同的目的。 什么是一些实际的原因使用null而不是undefined

空和未定义实际上是两个不同的值,意味着同样的事情。 唯一的区别在于你如何在你的系统中使用它们。 正如一些人所说,有些人使用null来表示“没有对象”,有时你可能会得到一个对象,而未定义则意味着没有预期的对象(或者有错误)。 我的问题是它完全武断,完全没有必要。

也就是说,有一个主要区别 – 未初始化的variables(包括未传递参数的函数参数等) 始终未定义。

这就是为什么在我的代码,我从来没有使用null,除非我不控制返回null(正则expression式匹配例如)。 这个美妙之处在于它使事情变得非常复杂。 我从来没有检查如果x === undefined || x === null。 如果你习惯使用==或者只是像(x)…这样的东西。 停下来。 !x将为空string计算为true,0,null,NaN – 即您可能不想要的东西。 如果你想写的不是很糟糕的JavaScript,总是使用三等于===,并从不使用null(使用undefined代替)。 这会让你的生活更轻松。

我没有真正的答案,但根据N. Zakas,p。 对于Web开发人员Javascript的 30:

当定义一个variables以便稍后保存一个对象时,build议将该variables初始化为null而不是其他任何东西。 这样,您可以显式检查值为null以确定variables是否在以后用对象引用填充

你可能会采用这里提出的惯例,但实际上没有什么好的理由。 它没有被一贯地使用来有意义。

为了使惯例有用,你首先必须知道被调用的函数遵循惯例。 那么你必须明确地testing返回值并决定要做什么。 如果你不确定 ,你可以假设被调用的函数知道发生了某种错误。 但是如果发生了错误,并且函数知道了它,并且将它发送到更广泛的环境中是非常有用的,那么为什么不使用错误对象呢? 即抛出一个错误?

所以在一天结束的时候,这个约定在简单的环境中对于非常小的程序来说实际上是无用的。

未定义的是没有事物的概念存在; 它没有types,在这个范围之前从来没有被引用。 null是事物已知存在的地方,但它没有价值。

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

假设你正在使用像jQuery插件的选项那样的对象属性…问自己JavaScript给了一个尚未定义的属性的值 – 答案是undefined 。 所以在这种情况下,我会初始化这些types的东西与'未定义'是一致的JavaScript(对于variables,你可以做var myVar;而不是var myVar = undefined; )。

现在让我们假设你正在做DOM操作… JavaScript分配给不存在的元素有什么价值? 答案是null 。 如果您要创build一个占位符variables,稍后将保存对与DOM相关的元素,文档片段或类似对象的引用,则这是我将初始化的值。

如果您使用的是JSON,则需要特殊情况:对于未定义的属性值,应将其设置为""null因为undefined的值undefined被视为正确的JSON格式。

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

DOM节点和元素不是未定义的,但可能为空。

  • 元素的最后一个子元素的nextSibling是null。

  • 第一个孩子的前一个兄弟是空的。

  • 如果文档中不存在元素,则document.getElementById引用为null。

但是在这些情况中,没有一个是未定义的 。 那里没有节点。

我完全不同意使用null或undefined是不必要的。 undefined是保持整个原型链接过程的东西。 所以编译器只能使用null,不能检查这个属性是否等于null,或者它在端点原型中没有定义。 在其他dynamictypes语言(fe Python)中,如果你想访问未定义的属性,它会抛出exception,但是对于基于原型的语言,编译器还应该检查父类的原型,这里是未定义最需要的地方。

使用null的整体含义就是绑定variables或者是具有单一对象的属性,具有空的含义,空使用也有性能目的。 这2个代码有不同的执行时间。

 var p1 = function(){this.value = 1}; var big_array = new Array(100000000).fill(1).map((x, index)=>{ p = new p1(); if(index > 50000000){ px = "some_string"; } return p; }); big_array.reduce((sum, p)=> sum + p.value, 0) var p2 = function(){this.value = 1, px = null}; var big_array = new Array(100000000).fill(1).map((x, index)=>{ p = new p2(); if(index > 50000000){ px = "some_string"; } return p; }); big_array.reduce((sum, p)=> sum + p.value, 0) 

未定义的 null中的有用属性不具有限定条件:

 > null + 3 3 > undefined + 3 NaN 

当我想closures一个数值或者初始化一些数据时,我使用null 。 我最后的用处是操纵CSS转换:

 const transforms = { perspective : null, rotateX : null }; // if already set, increase, if not, set to x runTimeFunction((x) => { trasforms.perspective += x; }); // still useful, as setting perspective to 0 is different than turning it off runTimeFunction2((x) => { transforms.perspective = null; }); // toCss will check for 'null' values and not set then at all runTimeFunction3(() => { el.style.transform = toCss(transforms); }); 

不知道我是否应该使用这个财产思想…

我现在正在通过这个确切的问题,看看下面的哲学:

  1. 任何意图返回结果的函数如果找不到结果,都应该返回null
  2. 任何不打算返回结果的函数都会返回undefined。

对于我来说,这个问题很重要,因为任何调用返回结果的函数的人都不应该怀疑是否testingundefined vs null。

这个答案不试图解决:

  1. null与未定义的属性值
  2. 你的函数中的variables是null与undefined

在我看来,variables是你自己的业务,而不是你的API的一部分,任何OO系统中的属性都是定义的,因此应该定义与它们在未定义时的值不同的值(null为已定义,undefined为你当访问不在你的对象中的东西时得到)。

这是一个原因: var undefined = 1是合法的javascript,但是var null = 1是一个语法错误。 不同之处在于null是一个语言关键字,而undefined是由于某种原因而不是。

如果你的代码依赖于undefined比较,如果它是一个关键字( if (foo == undefined) – 这是一个非常容易的错误),因为没有人定义了一个variables名称。 所有这些代码容易被意外或恶意地定义一个具有该名称的全局variables。 当然,我们都知道,无意中定义一个全局variables是完全不可能在JavaScript中…