JavaScript 中的 null 和 undefined 有什么区别?

What is the difference between null and undefined in JavaScript?

提问人: 提问时间:2/22/2011 最后编辑:Abdullah Khan 更新时间:10/5/2023 访问量:657663

问:

JavaScript 和 有什么区别?nullundefined

JavaScript null 未定义

评论

32赞 Muhammad Umer 9/13/2014
我一直在想:你是不是把它设置为空的,它是空的,因为它没有被设置。或者故意是空的,而仍然是空的。基本上,它显示了意图。nullundefinednullundefined
1赞 Bergi 9/24/2014
另请参阅 为什么 null 是对象,null 和 undefined 有什么区别?
65赞 Ivan 4/22/2016
南。亲眼看看吧。控制台.log(null-未定义)。null 和 undefined 之间的区别在于 NaN。(请注意,这是幽默的尝试,在你因为误解问题而激怒我之前。
0赞 AL-zami 9/20/2017
了解 undefined 及其与范围 codepen.io/grumpy/post/undefined-scope-in-javascript 的关系
0赞 Robert 11/19/2017
通常使用它来擦除变量的内容,当尚未设置值时,它通常带有输入。nullundefined
1赞 Chris Collett 7/18/2022
顺便说一句,值得一提的是,虽然 JavaScript 的创始人称其为“十亿美元的错误”(Tony Hoare),但 JavaScript 很高兴地决定将这个错误乘以 2。祝您调试愉快!null

答:

1563赞 sebastian 2/22/2011 #1

undefined表示已声明变量但尚未赋值:

var testVar;
console.log(testVar); //shows undefined
console.log(typeof testVar); //shows undefined

null是赋值。它可以赋值给变量作为无值的表示:

var testVar = null;
console.log(testVar); //shows null
console.log(typeof testVar); //shows object

从前面的例子中可以清楚地看出,和是两种不同的类型:是类型本身(未定义),而是对象。undefinednullundefinednull

证明:

console.log(null === undefined) // false (not the same type)
console.log(null == undefined) // true (but the "same value")
console.log(null === null) // true (both type and value are the same)

null = 'value' // Uncaught SyntaxError: invalid assignment left-hand side
undefined = 'value' // 'value'

评论

451赞 Captain Sensible 11/3/2011
引用《Professional JS For Web Developers》(Wrox)一书:“你可能想知道为什么typeof运算符为null值返回'object'。这实际上是原始 JavaScript 实现中的一个错误,然后被复制到 ECMAScript 中。今天,null 被认为是对象的占位符,尽管从技术上讲,它是一个原始值,这被合理化了。
53赞 Nir O. 5/9/2012
变量可能根本不定义。例如:console.log(typeof(abc));定义
28赞 Wolfgang Adamec 9/26/2012
Nir O. 的评论非常重要。如果我想有一个开头没有值的变量,我会写“... = null”,例如“myvar = null”。这样 - 当我错误地输入“if (myxar == null) {...}” - if 块不会执行。我没有这个优势 undefined: myvar = undefined;myvar = 4;if (typeof myxar == “undefined”) { ...}
19赞 Jorge Fuentes González 3/16/2013
@Wolfgang Adamec 来说,无错误编程与错误类型无关。
17赞 Muhammad Umer 8/10/2013
因此,基本上 null 值意味着变量已被显式设置为 (no value = null) 或已初始化并定义为 nothing。虽然未定义意味着。它可能从未初始化过,或者如果初始化,它从未被定义过。
89赞 ayush 2/22/2011 #2

我从这里选了这个

undefined 值是变量没有 被赋值。

null 值是一个基元值,表示 null、空、 或不存在的引用。

当您通过 var 声明一个变量并且不给它一个值时,它将具有未定义的值。就其本身而言,如果您尝试 WScript.Echo() 或 alert() 此值,您将看不到任何内容。但是,如果你在它后面附加一个空白字符串,那么它会突然出现:

var s;
WScript.Echo(s);
WScript.Echo("" + s);

您可以声明一个变量,将其设置为 null,并且行为是相同的,只是您会看到“null”打印出来与“undefined”。这确实是一个很小的差异。

您甚至可以将未定义的变量与 null 进行比较,反之亦然,条件将为 true:

undefined == null
null == undefined

然而,它们被认为是两种不同的类型。虽然 undefined 本身就是一个类型,但 null 被认为是一个特殊的对象值。你可以通过使用 typeof() 来查看这一点,它返回一个表示变量的一般类型的字符串:

var a;
WScript.Echo(typeof(a));
var b = null;
WScript.Echo(typeof(b));

运行上述脚本将产生以下输出:

undefined
object

无论它们属于不同的类型,如果您尝试访问其中任何一个的成员,它们仍然会执行相同的操作,例如,也就是说它们会抛出异常。使用 WSH,你会看到可怕的“'varname' is null or not an object”,这是如果你幸运的话(但这是另一篇文章的主题)。

您可以显式地将变量设置为未定义,但我强烈建议不要这样做。我建议只将变量设置为 null,而对于忘记设置的内容,则不定义值。同时,我真的鼓励你始终设置每个变量。JavaScript 的作用域链与 C 风格的语言不同,即使是资深程序员也很容易混淆,将变量设置为 null 是防止基于它的错误的最佳方法。

您将看到未定义弹出窗口的另一个实例是使用 delete 运算符时。我们这些来自C世界的人可能会错误地将其解释为破坏一个物体,但事实并非如此。此操作的作用是从 Array 中删除下标或从 Object 中删除成员。对于数组,它不会影响长度,而是将下标视为未定义。

var a = [ 'a', 'b', 'c' ];
delete a[1];
for (var i = 0; i < a.length; i++)
WScript.Echo((i+".) "+a[i]);

上述脚本的结果是:

0.) a
1.) undefined
2.) c

在读取从未存在的下标或成员时,您还将返回 undefined。

null 和 undefined 的区别在于:JavaScript 永远不会将任何内容设置为 null,我们通常就是这样做的。虽然我们可以将变量设置为未定义,但我们更喜欢 null,因为它不是为我们做的事情。当你调试时,这意味着任何设置为 null 的事情都是你自己做的,而不是 JavaScript。除此之外,这两个特殊值几乎是相等的。

评论

9赞 wOlVeRiNe 2/17/2014
真的是一个很好的答案。但需要指出的是,当您检查“undefined == null”时,类型检查并不严格。因此,它返回“true”。如果选中“undefined === null”,它将返回 false。
4赞 0x24a537r9 2/15/2018
值得注意的是,虽然这个评论在 11 年是正确的,但随着可选函数参数的出现、Flow 等类型检查系统的出现以及 React 的普及(所有这些都非常不同地对待 undefined 和 null),通常使用 null 而不是 undefined 的旧智慧不再那么严格。在许多情况下,undefined 实际上比 null 更可取,因为您希望显式使用默认值(例如,对于可选参数或可选的 React 属性)。
0赞 Michael Freidgeim 1/8/2022
blog.devgenius.io/...“在我看来,最好不要使用 null,更喜欢 undefined。”
10赞 Chris 2/22/2011 #3

未定义表示已声明变量但没有值:

var var1;
alert(var1); //undefined
alert(typeof var1); //undefined

Null 是赋值:

var var2= null;
alert(var2); //null
alert(typeof var2); //object
15赞 Richard H 2/22/2011 #4

null是一个特殊值,意思是“没有价值”。 是一个特殊对象,因为返回 'object'。nulltypeof null

另一方面,表示变量尚未声明,或尚未被赋予值。undefined

评论

3赞 Yura 10/18/2015
需要注意的是,while 可能意味着变量尚未声明,但不能保证。变量可以声明为 ,并且等于 。undefinedvar thing;undefined
27赞 Dmitry Sychov 7/3/2011 #5

null:变量没有值;undefined:没有变量本身;

..其中 variable 是与值关联的符号名称。

JS 可以善意地用 null 隐式初始化新声明的变量,但事实并非如此。

评论

34赞 Muhammad Umer 3/6/2015
var a = {}; a.n = undefined;' then ..a.hasOwnProperty('n') == true' ...因此,说没有变量本身已经不正确了
0赞 Steve Bennett 6/23/2021
这是一个非常简洁的定义,但它并不准确——因为你给出的原因。定义的变量以值 开头。undefined
0赞 Aman Godara 11/29/2021
即使这个答案被发布这么多年,我想我同意这个答案。的意图是变量不存在,而 的意图是该变量存在但没有值。窥视者通过检查变量来深入了解特定于实现的细节,但错过了理解 CS 中最强大的术语之一,称为“抽象”。undefinednulltypeof
3赞 Srinivas Kothuri 8/6/2012 #6

由于 typeof 返回 undefined,undefined 是一种类型,其中 null 是初始值设定项表示变量不指向任何对象(实际上 Javascript 中的所有内容都是对象)。

4赞 Praveen 10/8/2013 #7

null 和 undefined 都用于表示缺少某个值。

var a = null;

a 已初始化并定义。

typeof(a)
//object

null 是 JavaScript 中的对象

Object.prototype.toString.call(a) // [object Object]

var b;

b 未定义且未初始化

未定义的对象属性也是未定义的。例如,“x”未在对象 c 上定义,如果您尝试访问 c.x,它将返回 undefined。

通常,我们将 null 分配给未定义的变量。

评论

1赞 Paul S. 4/29/2015
Object.prototype.toString.call(null); // "[object Null]"
43赞 Mina Gabriel 10/26/2013 #8

null 是一个特殊关键字,表示缺少值。

可以把它看作一个值,比如:

  • “foo”是字符串,
  • true 是布尔值,
  • 1234 是数字,
  • null 未定义。

undefined 属性表示变量尚未被赋值,包括 null 。 喜欢

var foo;

定义的空变量为数据类型未定义的 null


它们都表示没有值的变量的值

AND 不表示没有值的字符串 - 空字符串 -null


喜欢

var a = ''; 
console.log(typeof a); // string 
console.log(a == null); //false 
console.log(a == undefined); // false 

现在如果

var a;
console.log(a == null); //true
console.log(a == undefined); //true 

var a; 
console.log(a === null); //false 
console.log(a === undefined); // true

所以每个人都有自己的使用方式

undefined 用它来比较变量数据类型

null 用它来清空变量的值

var a = 'javascript';
a = null ; // will change the type of variable "a" from string to object 

评论

2赞 danwellman 6/21/2014
null 也是一种数据类型。undefined 和 null 都是数据类型和值
15赞 danwellman 6/26/2014
null绝对是数据类型:msdn.microsoft.com/en-us/library/ie/7wkd9z69(v=vs.94).aspx 。事实上,return 是 ECMAScript 早期版本中一个众所周知且有据可查的错误,它一直保留下来以保持向后兼容性。实际在评论中发布的链接在页面中途说“typeof null // object (bug in ECMAScript, should be null)”!因此,请在评论反对票之前进行一些搜索工作typeof nullobject
2赞 Zon 1/26/2016
定义自相矛盾:“没有价值”与“没有被赋予价值”。不是一样吗?
4赞 alaboudi 1/4/2017
我不同意这个答案。Null 和 undefined 都是不同的数据类型。null 的类型为 null,undefined 的类型为 undefined。只有当使用真运算符 (==) 时,我们才能看到 javascript 说它是真的,但严格的比较 (===) 会产生一个假的。
1赞 Sebastian Simon 8/9/2021
直到今天,“null is undefined”仍然是错误的。
8赞 dinesh_malhotra 2/19/2014 #9

在 JavasScript 中,有 5 种原始数据类型:String、Number、Boolean、null 和 undefined。 我将尝试用一些简单的例子来解释。

假设我们有一个简单的函数

 function test(a) {
     if(a == null) {
        alert("a is null");
     } else {
        alert("The value of a is " + a);
     }
  }

此外,上面与 相同。function if(a == null)if(!a)

现在,当我们调用这个函数而不传递参数

test(); // will alert "a is null";
test(4); // will alert "The value of a is " + 4;

var a;
alert(typeof a);

这将给出 undefined;我们已经声明了一个变量,但我们没有为这个变量赋值;

但是如果我们写

var a = null;
alert(typeof a); // will give alert as object

所以 null 是一个对象。在某种程度上,我们为“a”分配了一个值 null

评论

0赞 Alexander Mills 10/26/2017
Symbol 是一种新的基元类型:)
0赞 jimmyfever 10/8/2021
在上面的示例中,它仅为真,因为 和 在真实上相等(为假)。如果您在没有参数的情况下调用,它将是 .a == nullnullundefinednull === undefinedtest()undefined
0赞 Ray Toal 10/13/2021
2020 年更新:现在有种基元类型。自从写这个答案以来,添加了 Symbol 和 BigInt。
13赞 R.G. 3/16/2014 #10

nullundefined 是两种不同的对象类型,它们具有以下共同点:

  • 两者都只能保存一个值,分别为 nullundefined;
  • 两者都没有属性或方法,尝试读取任何一个属性的任何属性都会导致运行时错误(对于所有其他对象,如果尝试读取不存在的属性,则会获得 value undefined);
  • nullundefined 被 和 运算符视为彼此相等,并且不等于其他任何值。==!=

然而,相似之处到此为止。这一次,关键字 nullundefined 的实现方式存在根本差异。这并不明显,但请考虑以下示例:

var undefined = "foo";
WScript.Echo(undefined); // This will print: foo

undefinedNaNInfinity 只是预先初始化的“超全局”变量的名称 - 它们在运行时初始化,可以被具有相同名称的普通全局变量或局部变量覆盖。

现在,让我们尝试使用 null 做同样的事情:

var null = "foo"; // This will cause a compile-time error
WScript.Echo(null);

哎呀!nulltruefalse 是保留关键字 - 编译器不允许将它们用作变量或属性名称

另一个区别是 undefined 是基元类型,而 null 是对象类型(表示对象引用的缺失)。请考虑以下几点:

WScript.Echo(typeof false); // Will print: boolean
WScript.Echo(typeof 0); // Will print: number
WScript.Echo(typeof ""); // Will print: string
WScript.Echo(typeof {}); // Will print: object
WScript.Echo(typeof undefined); // Will print: undefined
WScript.Echo(typeof null); // (!!!) Will print: object

此外,在数字上下文中处理 nullundefined 的方式也存在重要差异:

var a; // declared but uninitialized variables hold the value undefined
WScript.Echo(a === undefined); // Prints: -1

var b = null; // the value null must be explicitly assigned 
WScript.Echo(b === null); // Prints: -1

WScript.Echo(a == b); // Prints: -1 (as expected)
WScript.Echo(a >= b); // Prints: 0 (WTF!?)

WScript.Echo(a >= a); // Prints: 0 (!!!???)
WScript.Echo(isNaN(a)); // Prints: -1 (a evaluates to NaN!)
WScript.Echo(1*a); // Prints: -1.#IND (in Echo output this means NaN)

WScript.Echo(b >= b); // Prints: -1 (as expected)
WScript.Echo(isNaN(b)); // Prints: 0 (b evaluates to a valid number)
WScript.Echo(1*b); // Prints: 0 (b evaluates to 0)

WScript.Echo(a >= 0 && a <= 0); // Prints: 0 (as expected)
WScript.Echo(a == 0); // Prints: 0 (as expected)
WScript.Echo(b >= 0 && b <= 0); // Prints: -1 (as expected)
WScript.Echo(b == 0); // Prints: 0 (!!!)

null 在算术表达式或数值比较中使用时变为 0 - 与 false 类似,它基本上只是一种特殊的“零”。另一方面,undefined 是真正的“无”,当您尝试在数字上下文中使用它时,它会变成 NaN(“不是数字”)。

请注意,nullundefined 从 和 运算符获得特殊处理,但您可以使用表达式 测试 ab 的真数值相等性。==!=(a >= b && a <= b)

17赞 Kevin 6/29/2014 #11

您可以将 undefined 视为表示系统级、意外或类似错误的缺失值,而 null 表示程序级、正常或预期缺失值。

通过 JavaScript:权威指南

评论

0赞 Arad Alvand 3/1/2021
我真的很喜欢这个描述。
0赞 Stevenfowler16 4/27/2021
这也是我想我会用到的。如果我收到 null,我知道该值是故意设置为 null 的
-4赞 Hoven 8/18/2014 #12

只是为了补充我的观点——

如果像 C++ 这样的编译语言,优化编译器会删除仅声明且从未在任何地方使用的变量[或在 IDE 中标记警告]。这最终意味着该变量不存在,因为它的内存从未分配过。

在javascript解释器的情况下,[我猜]一个变量只从它被赋予值的点开始被视为存在。在此之前,它的类型是“未定义”的,并且没有为其分配内存。而且,它的类型是未定义的。

javascript 中的 null 表示地址的值,但该地址尚未指向任何内容[不存在的引用]。尽管如此,它仍然是一个价值。

评论

0赞 Bergi 8/18/2014
不,需要分配一些内存来区分已声明(尚未)变量和未声明的变量。 也只是一个值,它是未初始化变量的默认值。undefinedundefined
0赞 Hoven 8/18/2014
我不了解 js 解释器是如何工作的,但猜测是基于这样一个事实,即应用于不存在的变量的 typeof 运算符和仅声明的变量会产生相同的“未定义”字符串。我对未声明的变量获得默认原始值 undefined 这一事实表示怀疑[也许,对解释器有内部知识的人可以澄清这一点],即使比较会返回 true。在 ECMA-262 之前没有未定义的值?
0赞 Bergi 8/18/2014
对于这两种情况,具有相同的输出并不意味着什么(尽管它可能暗示了 netscape 中的原始实现)。诚然,优化编译器可能在分配堆栈变量之前不会分配堆栈变量,但我不认为各种实现中的非优化变量(注意:该语言没有一个解释器)这样做 - 毕竟,ES 规范说变量环境是按调用初始化的。typeof
1赞 Hoven 8/28/2014
经过研究,我发现我的观点是不正确的。请参阅第 12.2 节 ECMA 标准 - ecma-international.org/ecma-262/5.1/#sec-12.2 引用:变量语句声明按照 10.5 中的定义创建的变量。变量在创建时初始化为 undefined。而且,在下面的链接中,第 2 点澄清了未声明的变量实际上仅在初始化时创建,否则不会 - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/......
-4赞 AbbyPaden 10/23/2014 #13

Null 始终是内存中存在的未知对象,而 undefined 则不是。

3赞 Sandip Nirmal 2/1/2015 #14

null - 它是一个赋值,它与变量一起使用以表示没有值(它是一个对象)。

undefined - 它是一个变量,没有任何赋值给它,所以 JavaScript 会给它赋值一个 undefined(它是一种数据类型)。

undeclare - 如果根本没有创建变量,则称为 undeclared。

-2赞 NavyaKumar 2/23/2015 #15

如果变量未初始化,则该变量未定义。 undefined 不是对象。 示例:var MyName; console.log(类型为MyName);

在开发工具中检查控制台日志,它会被打印为未定义。

null 是一个对象。如果你想让某个变量为 null,则使用 null.null 变量存在,但值未知。它应该在语法上分配给一个变量。null 不会自动初始化。

示例:var MyName = null; console.log(类型为MyName); 检查开发工具中的 csole 日志,它将是一个对象。

2赞 Stacked 8/8/2015 #16

和 之间的区别很小,但有区别。其值为 的变量从未初始化过。显式指定其值为 的变量的值为 ,这意味着该变量被显式设置为没有值。如果比较并使用表达式,它们将相等。undefinednullundefinednullnullundefinednullnull==undefined

评论

0赞 Guy 11/11/2015
这个答案具有误导性......请参阅已接受的答案中的讨论。底线 - 只是因为隐式转换(或 JS 中的等效术语)。显然,这是因为在使用它时使用也会比较类型null==undefinedtruenull===undefinedfalse===
4赞 bholben 11/8/2015 #17

根据瑞安·莫尔(Ryan Morr)关于这个主题的详尽文章......

“一般来说,如果你需要为变量或属性赋值,将其传递给函数,或从函数返回它,null 几乎总是最佳选择。简单地说,JavaScript 使用 undefined,程序员应该使用 null。

请参阅探索 Null 和 Undefined 的永恒深渊

5赞 zangw 12/25/2015 #18

对于类型,有一个且只有一个值:。undefinedundefined

对于类型,有一个且只有一个值:。nullnull

因此,对于它们来说,标签既是它的类型,也是它的价值。

它们之间的区别。例如:

  • null为空值
  • undefined是缺失值

艺术

  • undefined还没有值
  • null有价值,不再有价值了

实际上,是一个特殊的关键字,而不是标识符,因此您不能将其视为要赋值的变量。null

但是,是一个标识符。但是,在模式和模式下,您都可以创建名称为 undefined 的局部变量。但这是一个可怕的主意!undefinednon-strictstrict

function foo() {
    undefined = 2; // bad idea!
}

foo();

function foo() {
    "use strict";
    undefined = 2; // TypeError!
}

foo();
12赞 BERGUIGA Mohamed Amine 2/10/2016 #19

我会解释,并且:undefinednullUncaught ReferenceError

1 - :脚本中尚未声明变量,没有引用此变量
2 - :已声明变量但未初始化
3 - :已声明变量,为空值
Uncaught ReferenceErrorundefinednull

67赞 Arup Hore 9/21/2016 #20

请仔细阅读以下内容。它应该消除您对 JavaScript 和 JavaScript 之间差异的所有疑虑。此外,您可以使用此答案末尾的实用程序函数来获取更具体类型的变量。nullundefined

在 JavaScript 中,我们可以有以下类型的变量:

  1. 未声明的变量
  2. 已声明但未赋值的变量
  3. 使用文本分配的变量undefined
  4. 使用文本分配的变量null
  5. 分配了除 或 以外的任何变量undefinednull

下面逐一解释这些情况:

  1. 未声明的变量

    • 只能使用返回字符串“undefined”的运算符进行检查typeof
    • 不能使用松散相等运算符 ( ) 进行检查,更不用说严格相等运算符 ( ) 以及 if 语句三元运算符 ( )
      — 这些会引发引用错误
      == undefined=== undefined? :
  2. 已声明但未赋值的变量

    • typeof返回字符串“undefined”
    • ==检查退货nulltrue
    • ==检查退货undefinedtrue
    • ===检查退货nullfalse
    • ===检查退货undefinedtrue
    • 对 if 语句三元运算符伪造的 ( ? : )
  3. 使用文本未定义
    分配的变量 这些变量的处理方式与已声明但未分配的变量完全相同。

  4. 赋值为文本 null 的变量

    • typeof返回字符串 'object'
    • ==检查退货nulltrue
    • ==检查退货undefinedtrue
    • ===检查退货nulltrue
    • ===检查退货undefinedfalse
    • 对 if 语句三元运算符伪造的 ( ? : )
  5. 分配了除 undefinednull 以外的任何变量

    • typeof 返回以下字符串之一: 'bigint', 'boolean', 'function', 'number', 'object', 'string', 'symbol'

下面提供了用于正确检查变量类型的算法:

  1. 获取我们的变量,如果它不是“对象”,则返回它typeof
  2. 检查 ,因为也会返回 'object'nulltypeof null
  3. 使用 switch 语句计算 Object.prototype.toString.call(o) 以返回更精确的值。的方法返回类似于本机/主机对象的“[object ConstructorName]”的字符串。对于所有其他对象(用户定义的对象),它始终返回“[object Object]”ObjecttoString
  4. 如果最后一部分是这种情况(变量的字符串化版本是 '[object Object]'),并且参数 returnConstructorBoolean 是 ,它将尝试通过 -ing 它并从那里提取名称来获取构造函数的名称。如果无法访问构造函数,则像往常一样返回“object”。如果字符串不包含其名称,则返回“anonymous”truetoString

(支持最高 ECMAScript 2020 的所有类型)

function TypeOf(o, returnConstructorBoolean) {
  const type = typeof o

  if (type !== 'object') return type
  if (o === null)        return 'null'

  const toString = Object.prototype.toString.call(o)

  switch (toString) {
    // Value types: 6
    case '[object BigInt]':            return 'bigint'
    case '[object Boolean]':           return 'boolean'
    case '[object Date]':              return 'date'
    case '[object Number]':            return 'number'
    case '[object String]':            return 'string'
    case '[object Symbol]':            return 'symbol'

    // Error types: 7
    case '[object Error]':             return 'error'
    case '[object EvalError]':         return 'evalerror'
    case '[object RangeError]':        return 'rangeerror'
    case '[object ReferenceError]':    return 'referenceerror'
    case '[object SyntaxError]':       return 'syntaxerror'
    case '[object TypeError]':         return 'typeerror'
    case '[object URIError]':          return 'urierror'

    // Indexed Collection and Helper types: 13
    case '[object Array]':             return 'array'
    case '[object Int8Array]':         return 'int8array'
    case '[object Uint8Array]':        return 'uint8array'
    case '[object Uint8ClampedArray]': return 'uint8clampedarray'
    case '[object Int16Array]':        return 'int16array'
    case '[object Uint16Array]':       return 'uint16array'
    case '[object Int32Array]':        return 'int32array'
    case '[object Uint32Array]':       return 'uint32array'
    case '[object Float32Array]':      return 'float32array'
    case '[object Float64Array]':      return 'float64array'
    case '[object ArrayBuffer]':       return 'arraybuffer'
    case '[object SharedArrayBuffer]': return 'sharedarraybuffer'
    case '[object DataView]':          return 'dataview'

    // Keyed Collection types: 2
    case '[object Map]':               return 'map'
    case '[object WeakMap]':           return 'weakmap'

    // Set types: 2
    case '[object Set]':               return 'set'
    case '[object WeakSet]':           return 'weakset'

    // Operation types: 3
    case '[object RegExp]':            return 'regexp'
    case '[object Proxy]':             return 'proxy'
    case '[object Promise]':           return 'promise'

    // Plain objects
    case '[object Object]':
      if (!returnConstructorBoolean)
        return type

      const _prototype = Object.getPrototypeOf(o)
      if (!_prototype)              
        return type

      const _constructor = _prototype.constructor
      if (!_constructor)            
        return type

      const matches = Function.prototype.toString.call(_constructor).match(/^function\s*([^\s(]+)/)
        return matches ? matches[1] : 'anonymous'

    default: return toString.split(' ')[1].slice(0, -1)
  }
}
2赞 Zaid Khan 12/18/2016 #21

基本上,Undefined 是 javascript 在运行时创建的全局变量,无论 null 是否意味着没有为变量赋值(实际上 null 本身就是一个对象)。

让我们举个例子:

        var x;  //we declared a variable x, but no value has been assigned to it.
        document.write(x) //let's print the variable x

未定义,这就是您将获得的输出。

现在

        x=5;
        y=null;
        z=x+y;

您将获得 5 作为输出。这就是 Undefinednull 之间的主要区别

4赞 poushy 1/14/2017 #22

在 javascript 中,所有变量都存储为键值对。每个变量都存储为 variable_name : variable_value/reference

undefined 表示变量在内存中被赋予了空间,但没有为其赋值。最佳做法是,不应将此类型用作赋值。

在这种情况下,如何表示您希望变量在代码的稍后时间点没有值?您可以使用 null 类型,这也是一种用于定义相同事物的类型,没有值,但它与 undefined 不同,因为在这种情况下,您实际上在内存中拥有值。该值为 null

两者相似,但用法和含义不同。

9赞 Bruno J. S. Lesieur 1/20/2017 #23

tl;博士

用于设置一个变量,你知道它是一个对象。null

用于设置类型为混合的变量。undefined


这是我对 5 个基元和对象类型的用法,它解释了 或 的“用例”之间的区别。undefinednull

字符串

如果你知道一个变量在整个生命周期中只是一个字符串,按照惯例,你可以将其初始化为:""

("") ? true : false; // false
typeof ""; // "string";
("Hello World") ? true : false; // true
typeof "Hello World"; // "string"

如果你知道一个变量在整个生命周期中只是一个数字,按照惯例,你可以将其初始化为(或者如果是你用法中的一个重要值):0NaN0

(0) ? true : false; // false
typeof 0; // "number";
(16) ? true : false; // true
typeof 16; // "number"

(NaN) ? true : false; // false
typeof NaN; // "number";
(16) ? true : false; // true
typeof 16; // "number"

布尔

如果您知道一个变量在整个生命周期中都只是一个布尔值,按照惯例,您可以将其初始化为:false

(false) ? true : false; // false
typeof false; // "boolean";
(true) ? true : false; // true
typeof true; // "boolean"

对象

如果您知道一个变量在整个生命周期中只是一个对象,按照惯例,您可以将其初始化为:null

(null) ? true : false; // false
typeof null; // "object";
({}) ? true : false; // true
typeof {}; // "object"

注意:智能用法 off null 是 Object 的虚假版本,因为 Object 始终为 true,并且因为 typeof null 返回对象。这意味着 typeof myVarObject 返回 Object 和 null 类型的一致值。

如果您知道某个变量具有混合类型(所有生命周期中的任何类型),则按照惯例,您可以将其初始化为 .undefined

6赞 Alireza 6/6/2017 #24

好吧,当我们听到 和 时,我们可能会感到困惑,但让我们从简单开始,它们都是虚假的,并且在很多方面都很相似,但是 JavaScript 的奇怪部分,使它们有几个显着的区别,例如,typeof 是而 typeof 是。nullundefinednull'object'undefined'undefined'

typeof null; //"object"
typeof undefined; //"undefined";

但是,如果您按以下方式检查它们,您会发现它们都是假的==

null==undefined; //true

此外,您可以分配给对象属性或原语,而可以通过不分配给任何内容来实现。nullundefined

我创建了一个快速图像,以便一目了然地为您显示差异。

Null and Undefined

6赞 psyborg.eth 10/7/2017 #25

当您在 javascript 中声明一个变量时,会为其赋值 。这意味着该变量保持不变,将来可以分配任何值。这也意味着您不知道此变量在声明时将保留的值。undefined

现在,您可以显式分配变量 。这意味着该变量没有任何值。例如,有些人没有中间名。因此,在这种情况下,最好将值 null 分配给 person 对象的中间名变量。null

现在假设有人正在访问你的 person 对象的中间名变量,并且它的值为 。他不知道开发人员是否忘记初始化这个变量,或者它是否没有任何值。如果它有值,那么用户可以很容易地推断出中间名没有任何值,它不是一个未触及的变量。undefinednull

17赞 Ray Toal 9/22/2018 #26

理解这种差异的最好方法是首先弄清楚 JavaScript 的内部工作原理,然后理解它们之间的含义差异:

let supervisor = "None"
    // I have a supervisor named "None"

let supervisor = null
    // I do NOT have a supervisor. It is a FACT that I do not.

let supervisor = undefined
    // I may or may not have a supervisor. I either don't know
    // if I do or not, or I am choosing not to tell you. It is
    // irrelevant or none of your business.

这三种情况在含义上存在差异,JavaScript 用两个不同的值来区分后两种情况,并且 .您可以自由地显式使用这些值来传达这些含义。nullundefined

那么,由于这种哲学基础而产生的一些特定于 JavaScript 的问题是什么?

  1. 没有初始值设定项的声明变量会获取该值,因为您从未说过预期值是什么。undefined

    let supervisor;
    assert(supervisor === undefined);
    
  2. 从未设置过的对象的属性的计算结果为,因为没有人对该属性说过任何话。undefined

    const dog = { name: 'Sparky', age: 2 };
    assert(dog.breed === undefined);
    
  3. null并且彼此“相似”,因为 Brendan Eich 是这么说的。但它们显然是不平等的。undefined

    assert(null == undefined);
    assert(null !== undefined);
    
  4. null值得庆幸的是,有不同的类型。 属于类型和类型。这在规范中,但你永远不会知道这一点,因为奇怪的是,我不会在这里重复。undefinednullNullundefinedUndefinedtypeof

  5. 一个没有显式 return 语句到达其主体末尾的函数会返回,因为您对它返回的内容一无所知。undefined

顺便说一句,JavaScript 中还有其他形式的“虚无”(学过哲学是件好事......

  • NaN
  • 使用从未声明过的变量并接收ReferenceError
  • 在其时间死区中使用或定义的局部变量并接收letconstReferenceError
  • 稀疏数组中的空单元格。是的,即使它们与未定义相比,它们也不是。undefined===

    $ node
    > const a = [1, undefined, 2]
    > const b = [1, , 2]
    > a
    [ 1, undefined, 2 ]
    > b
    [ 1, <1 empty item>, 2 ]
    

评论

0赞 J. Bruni 3/7/2020
最佳答案!大多数答案都忽略了这样一个事实,即您可以将变量的值定义为未定义,就像在案例中一样。let supervisor = undefined
0赞 Ray Toal 3/8/2020
谢谢你,是的,只有当某事没有被宣布或尚未被赋予价值时,这种误解是如此猖獗,而且真的很难传达给人们(尽管我一直在尝试)。很多人因为两者兼而有之而抨击 JavaScript,但这些值确实具有完全不同的含义,并且在大多数情况下,它们与预期含义配合得很好(恕我直言,当然)。undefinednullundefined
5赞 RBT 7/1/2019 #27

我想添加一个知识点,它与 nullundefined 之间的细微差别有关。当您尝试从头开始学习 Vanilla JavaScript(JS) 时,很高兴知道这一点:

null 是 JS 中的保留关键字,而 undefined 是 你所处的运行时环境的全局对象。

在编写代码时,这种差异是无法识别的,因为 nullundefined 始终用于 JavaScript 语句的右侧 (RHS)。但是,当您在表达式的左侧 (LHS) 中使用它们时,您可以轻松地观察到这种差异。所以JS解释器将下面的代码解释为错误:

var null = 'foo'

它给出以下错误:

未捕获的 SyntaxError:意外的令牌 null

同时,以下代码可以成功运行,尽管我不建议在现实生活中这样做:

var undefined = 'bar'

这之所以有效,是因为 undefined 是全局对象(在浏览器中运行 JavaScript 时为 window 对象)上的一个属性

评论

1赞 Dmitri Zaitsev 8/29/2019
undefined='bar'并没有真正分配任何值(这是不可变的),它只是不会令人困惑地抛出错误。undefined
704赞 Sebastian Norr 7/29/2019 #28

这种差异可以用卫生纸架来解释:

  • 非零值就像一个装着卫生纸卷的支架,管子上还有纸巾。

  • 零值就像一个装着空卫生纸管的支架。

  • null 值就像一个甚至没有组织管的支架。

  • 未定义的值类似于持有者本身的缺失。

评论

19赞 Vega 2/17/2020
您能否附上图片来源的归属?
11赞 Sebastian Norr 2/18/2020
@Vega 不幸的是,不,我不记得我从哪里得到它,除了 imgur.com 上的某个地方,这可能是来自转贴,而不是原始来源。甚至这里的嵌入式链接也没有提供任何关于谁发布了这个版本的线索,所以我也无法真正搜索它。
55赞 Erowlin 10/28/2020
@SebastianNorr “我不记得我从哪里得到它,除了 imgur.com 上的某个地方”——>那么是不是在这种情况下?undefinednull
105赞 Rain 2/26/2021
let toiletPaperIn2020 = undefined;
10赞 Stefaan Vandevelde 12/17/2021
undefined如果 holder 表示变量,则不能是空墙。在此表示中,是一个空的持有人,而 null 是一个带有便利贴的空持有人。(所以不幸的用户知道向清洁女工要卫生纸是没有用的)。这也说明了为什么许多开发人员感到困惑:我应该在未初始化的变量上贴上便利贴,还是每个人都会明白这意味着?例如,缺少卫生纸是有意还是无意?undefinedemptyemptyempty
2赞 Jayakumar Thangavel 11/18/2019 #29

这两个特殊值都表示空状态。

主要区别在于 undefined 表示尚未初始化的变量的值,而 null 表示有意缺少对象。

变量编号已定义,但是,未分配初始值:

let number;
number; // => undefined

number 变量未定义,这清楚地表明了未初始化的变量

当访问不存在的对象属性时,也会发生相同的未初始化概念:

const obj = { firstName: 'Dmitri' };
obj.lastName; // => undefined

由于 obj 中不存在 lastName 属性,因此 JavaScript 会正确地将 obj.lastName 计算为 undefined。

在其他情况下,您知道变量需要保存对象或函数以返回对象。但由于某种原因,您无法实例化该对象。在这种情况下,null 是缺少对象的有意义的指示器。

例如,clone() 是一个克隆纯 JavaScript 对象的函数。该函数应返回一个对象:

function clone(obj) {
  if (typeof obj === 'object' && obj !== null) {
    return Object.assign({}, obj);
  }
  return null;
}
clone({name: 'John'}); // => {name: 'John'}
clone(15);             // => null
clone(null);           // => null

但是,clone() 可以使用非对象参数调用:15 或 null(或者通常是原始值,null 或未定义)。在这种情况下,该函数无法创建克隆,因此它返回 null - 缺失对象的指示器。

Typeof 运算符对这两个值进行区分:

typeof undefined; // => 'undefined'
typeof null;      // => 'object'

严格的质量运算符 === 正确地区分了 undefined 和 null:

let nothing = undefined;
let missingObject = null;
nothing === missingObject; // => false
3赞 latitov 2/19/2020 #30

看看这个。输出胜过千言万语。

var b1 = document.getElementById("b1");

checkif("1, no argument"                        );
checkif("2, undefined explicitly",     undefined);
checkif("3, null explicitly",               null);
checkif("4, the 0",                            0);
checkif("5, empty string",                    '');
checkif("6, string",                    "string");
checkif("7, number",                      123456);

function checkif (a1, a2) {
	print("\ncheckif(), " + a1 + ":");
	if (a2 == undefined) {
		print("==undefined:    YES");
	} else {
		print("==undefined:    NO");
	}
	if (a2 === undefined) {
		print("===undefined:   YES");
	} else {
		print("===undefined:   NO");
	}
	if (a2 == null) {
		print("==null:         YES");
	} else {
		print("==null:         NO");
	}
	if (a2 === null) {
		print("===null:        YES");
	} else {
		print("===null:        NO");
	}
	if (a2 == '') {
		print("=='':           YES");
	} else {
		print("=='':           NO");
	}
	if (a2 === '') {
		print("==='':          YES");
	} else {
		print("==='':          NO");
	}
	if (isNaN(a2)) {
		print("isNaN():        YES");
	} else {
		print("isNaN():        NO");
	}
	if (a2) {
		print("if-?:           YES");
	} else {
		print("if-?:           NO");
	}
		print("typeof():       " + typeof(a2));
}

function print(v) {
	b1.innerHTML += v + "\n";
}
<!DOCTYPE html>
<html>
<body>
<pre id="b1"></pre>
</body>
</html>

另请参阅:

干杯!

评论

1赞 J. Bruni 3/7/2020
从中我实际上了解到回报 - 这让我感到惊讶。isNaN(null)false
9赞 Valeriy Katkov 5/28/2020 #31

除了不同的含义外,还有其他区别:

  1. 对象解构对这两个值的工作方式不同:
    const { a = "default" } = { a: undefined }; // a is "default"
    const { b = "default" } = { b: null };      // b is null
    
  2. JSON.stringify() 保留但省略nullundefined
    const json = JSON.stringify({ undefinedValue: undefined, nullValue: null });
    console.log(json); // prints {"nullValue":null}
    
  3. typeof 运算符
    console.log(typeof undefined); // "undefined"
    console.log(typeof null);      // "object" instead of "null"
    
2赞 Lu Tran 7/10/2020 #32

引自 Marijn Haverbeke 的“Eloquent Javascript”第 3 版:

和 之间含义的差异是 Javascript 设计的意外,大多数时候都无关紧要。如果您实际上必须关注这些值,我建议将它们视为大多数可以互换的undefinednull

老实说,起初,我对这个建议有点怀疑。然而,在我自己的解释中,这是处理他们差异的一种(与)方式。也许,我们根本不需要处理差异。如果我们必须这样做,我们可以延迟我们的关注(我们必须这样做的util),并且当这些值(和)流经我们的代码时,我们不必担心它的每一步。lazyeagerhyperactively/defensivelynullundefined

PS:这不是对你问题的直接回答。这只是一个相关意见。

-1赞 Jyotirmoy Upadhaya 11/4/2020 #33

在 Javascript 中,null 是一个空值或不存在的值,必须分配它。但 Undefined 表示已声明变量,但未定义 value。

let a = null;  
console.log(a);    // null
let b;         
console.log(b);    // undefined

在 JS 中,null 和 undefined 都是原始值。此外,您还可以查看以下代码行

console.log(typeof null); //Object
console.log(typeof undefined); //undefined
console.log(10+null); // 10
console.log(10+undefined); //NaN

评论

1赞 Linostar 2/16/2021
未声明的变量也具有未定义的类型。而 typeof undefined 是 “undefined”,而不是 “object”。
4赞 Alex Misiulia 2/18/2021 #34

undefined 和 null 之间的含义差异是 JavaScript 设计的意外,大多数时候并不重要。如果您实际上必须关注这些值,我建议将它们视为大多数可以互换的。

摘自 Eloquent Javascript 一书

0赞 UserName Name 6/1/2021 #35

null 的类型是 Object,而 undefined 的类型是 undefined。 Null 表示“没有值”,而 undefined 表示“不存在”。

typeof undefined; //undefined
typeof null; // Object
undefined !== null; //true
undefined == null; //true
undefined === null; //false
var var1;
var1; //undefined 
var var2 = null;
var2; //null
17赞 NicBright 7/1/2021 #36

已经给出了很多“技术”答案,从JS作为一种编程语言的有限角度来看,所有这些答案都是正确的。

但是,我想补充以下想法,尤其是当您将 TypeScript 代码作为更大的项目/(企业)应用程序的一部分编写时:

  • 当与某种后端交谈时,您很可能会收到 JSON
  • 虽然一些后端正确地避免在其 JSON 中使用“null”(删除这些属性),但其他后端则没有
  • 现在,虽然“null”可能意味着故意缺少该值,但更常见的是,它并不传达此含义。大多数数据库使用“null”只是因为它们没有“undefined”类型。但实际上的意思只是“未定义”。
  • 正因为如此,你永远无法知道“null”值是否真的意味着故意缺席。因此,“null”并不能真正意味着故意选择“缺失值”。一般来说,它是不可决定的。
  • 因此,从语义上讲,“null”和“undefined”在实践中是完全一样的。

因此,为了协调事情,我严格反对使用“null”,并希望鼓励您停止在代码中使用“null”。这比你想象的要容易得多。不要误会我的意思。我不是在谈论不处理“null”值,只是为了避免在代码中显式使用它们。换句话说:你的代码应该仍然能够处理来自应用程序外部的意外传递的“null”值,例如通过第三方库(如 Angular)或第三方后端。

以下是使之成为可能的准则:

  • 避免直接使用未定义的类型保护(例如.if (value === undefined) { ... }
  • 相反,使用间接类型保护(又名真实性检查),例如if (value) { ... }
    • 每当 0 或空字符串有意义时,请使用
      • 显式帮助程序方法,如 Lodash 的 isNil
      • 或在比较中包含有意义的值(例如if (!value && value !== 0) { ... })
  • 请考虑使用不允许使用 null 的 lint 规则

评论

0赞 Steven Coco 5/21/2022
这是一个有趣的视角,我认为可以扩展;这就是我发表此评论的原因。现在 C# 已经实现了不可为 null 的类型,如果你愿意这样称呼它,就会有一种“进步”,可以理解我所说的一些东西:如果你向数据库请求一个它没有的键,那么你就会返回 undefined,因为该键是 undefined;但是,如果您请求它确实具有的键,则对于任何非 null 的值,您都会返回 null — 您不会在那里返回 undefined。所以只是想知道失败是否在某种趋势中出现,或者你怎么称呼它?
2赞 jdmneon 7/15/2022
我完全同意这一点。更重要的是在生态系统的上下文中看待这一点,您通常不能像编程语言 Javascript 那样区分 Unknown 和 Null。事实上,这种情况很少是真的。因此,您不能假设 null 是有意为之的,因此您必须对它们一视同仁。当我们讨论一个从多个来源获取数据的程序,或者您无法控制数据源的结构时,尤其如此。在这种情况下,Javascript 的实际实现并不重要。
1赞 Nagev 11/10/2022
同意这比 .但是,当函数遇到错误时,函数会返回什么而不是对象呢?我认为这是显而易见的选择,但目前尚不清楚在这种情况下“停止在代码中使用”null“的建议是什么。if (value)if (value == null)return null
0赞 NicBright 12/1/2022
@Nagev:您需要决定是要直接在函数中处理错误,还是希望调用方处理错误。后者可以通过使函数实际抛出 Error 来轻松完成。前者可以通过仍然返回某种类型的对象(可能只有默认值或空或未定义的属性)来完成。或者,您可以返回并使其成为除对象之外的有效返回值(例如,考虑 TS 签名)。然后,呼叫者可以通过简单的真实性检查轻松跳过undefined(): YourType | undefinedundefinedif (...) {}
0赞 Nagev 12/2/2022
它们都是不错的选择,感谢您的澄清。我想这是一个偏好问题(当然,除非由代码库或团队约定决定)。就个人而言,我喜欢谨慎地抛出异常,因为我发现必须将所有内容都包装在 .在许多情况下,返回自定义对象可能过于复杂。并且测试对 和 一样有效,并且由于后者实际上是一个对象,因此当对象是返回类型时是有意义的。函数说:对不起,不能给你你想要的对象,这里是。try ... catchif (...)undefinednullnullnull
2赞 Lev Lukomskyi 7/21/2022 #37

一般来说,不要使用以避免混淆。null

  1. 标准库方法返回 ,而不是undefinednull
let a = [10];
console.log(a[1]) //=> undefined
console.log(a.find(value => value === 5)) //=> undefined
  1. 我经常在人们的代码中看到,一些变量首先是,然后被赋值给某个值,然后通过设置为 来清除。这不一致,最好回过头来。undefinednullundefined

尽管如此,如果框架使用它,或者用于 json 序列化,这是有道理的。null

0赞 mohit arora 7/28/2022 #38
const data  = { banners: null }
const { banners = [] } = data;
console.log(data)      // null


const data  = { banners: undefined }
const { banners = [] } = data;
console.log(data)      // []
1赞 Giulio 3/9/2023 #39

还要注意比较中的差异:

10 > undefined
false

10 < undefined
false

10 < null
false

10 > null
true