在JavaScript中,null和undefined之间有什么区别?

1645
在JavaScript中,nullundefined有什么区别?

32
我一直认为:null 表示你有意将其设置为空,而 undefined 是因为没有被设置而为空。或者说 null 是故意设置为空,而 undefined 则仍然为空。基本上这展示了意图。 - Muhammad Umer
64
看看这个。console.log(null-undefined)。null和undefined的区别是NaN。(请注意,这是一次幽默尝试,不要因为误解问题而批评我。) - Ivan
了解undefined及其与作用域的关系 https://codepen.io/grumpy/post/undefined-scope-in-javascript - AL-zami
1
值得一提的是,尽管“null”的发明者Tony Hoare称其为他的“十亿美元错误”,JavaScript却愉快地将这个错误乘以了2。祝你调试愉快! - Chris Collett
显示剩余5条评论
39个回答

13

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

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

然而,相似之处就在这里。首先,关键字nullundefined实现的方式存在根本性差异。这一点并不明显,但请考虑以下示例:

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

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

现在,让我们用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==!=运算符中接收特殊处理,但您可以使用表达式(a >= b && a <= b)测试ab的真实数值相等性。


12

我将解释 undefined, nullUncaught ReferenceError:

1 - Uncaught ReferenceError:在您的脚本中变量未被声明,没有引用此变量
2 - undefined:变量已声明但未初始化
3 - null:变量已声明且为空值


10

未定义意味着变量已被声明但没有值:

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

Null是一种赋值:

var var2= null;
alert(var2); //null
alert(typeof var2); //object

9

除了不同的含义,还有其他差异:

  1. Object destructuring works differently for these two values:
    const { a = "default" } = { a: undefined }; // a is "default"
    const { b = "default" } = { b: null };      // b is null
    
  2. JSON.stringify() keeps null but omits undefined
    const json = JSON.stringify({ undefinedValue: undefined, nullValue: null });
    console.log(json); // prints {"nullValue":null}
    
  3. typeof operator
    console.log(typeof undefined); // "undefined"
    console.log(typeof null);      // "object" instead of "null"
    

9

简洁版:

null 用于设置已知为对象的变量。

undefined 用于设置类型不确定的变量。


这是我使用五种基本类型和对象类型的方法,并解释了 undefinednull 的使用情况之间的区别。

字符串

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

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

数字

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

(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"

注意:null的聪明用法是作为对象的falsy版本,因为对象始终为true,而typeof null返回object。这意味着typeof myVarObject对于对象和null类型都返回一致的值。
全部:
如果您知道一个变量具有混合类型(任何类型在整个生命周期中),按照惯例,您可以将其初始化为undefined

8
在JavaScript中,有5种原始数据类型:String(字符串)、Number(数字)、Boolean(布尔值)、null和undefined。我将尝试用一些简单的例子来解释。
比如说我们有一个简单的函数。
 function test(a) {
     if(a == null) {
        alert("a is null");
     } else {
        alert("The value of a is " + a);
     }
  }

另外,在上面的代码中,if(a == null)if(!a)是等同的。

现在,当我们调用该函数而没有传递参数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是一个对象。我们已经将值null赋给了'a'。


符号是一种新的原始类型 :) - Alexander Mills
在你上面的 a == null 的例子中,它只是为真,因为 nullundefined 都是真实相等的(null === undefined 是假的)。如果你调用 test() 而没有参数,它将是 undefined - jimmyfever
2020年更新:现在有七种原始类型。自本答案编写以来,Symbol和BigInt已被添加。 - Ray Toal

6

好的,当我们听到 nullundefined 时可能会感到困惑,但让我们从简单的开始,它们都是 falsy 并且在很多方面都很相似,但 JavaScript 中奇怪的部分使它们有一些显著的区别,例如,typeof null'object' ,而 typeof undefined'undefined'

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

但如果你用如下的代码检查它们,使用==,你会发现它们都是falsy

null==undefined; //true

你可以将null分配给对象属性或原始值,而不分配任何值就能获得undefined
我制作了一张快速的图片,让你一目了然地了解它们之间的差异。 Null and Undefined

6
当你在javascript中声明一个变量时,它被赋予值undefined。这意味着该变量未被触及,可以在未来分配任何值。这也意味着你不知道在声明时该变量将要持有的值。
现在你可以显式地将变量null赋值。这意味着该变量没有任何值。例如 - 有些人没有中间名。因此,在这种情况下,最好将值null分配给人对象的middlename变量。
现在假设有人正在访问您的person对象的middlename变量,而它具有值undefined。他将不知道开发人员是否忘记初始化此变量或者它是否没有任何值。如果它具有值null,那么用户可以轻松推断middlename没有任何值,并且它不是一个未触及的变量。

5
对于类型 undefined,它只有一种值: undefined
对于类型 null,它只有一种值: null
因此,对于这两种类型的数据,标签既是类型也是值。 它们之间的区别如下所示:
  • null 是一个空值
  • undefined 是一个缺失的值
或者说:
  • undefined 还没有被赋值
  • null 曾经有过值,但现在已经没有了
实际上,null 是一个特殊的关键字,不是标识符,因此您不能将其作为变量来赋值。
然而,undefined 是一个标识符。 在非严格模式和严格模式下,您都可以创建一个名为 undefined 的局部变量。 但这是一个糟糕的主意!
function foo() {
    undefined = 2; // bad idea!
}

foo();

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

foo();

5
我想要添加一个知识点,它涉及到JavaScript中“null”和“undefined”的微妙区别。当你试图从基础开始学习纯JavaScript(JS)时,了解这一点非常重要:
“null”是JS中的保留关键字,而“undefined”是运行环境全局对象的属性。在编写代码时,由于“null”和“undefined”始终用于JavaScript语句的右侧(RHS),所以这种差异在代码中无法识别。但是,当您将它们用于表达式的左侧(LHS)时,就可以轻松观察到这种差异。因此,JS解释器会将下面的代码解释为错误:
var null = 'foo'

出现以下错误:

未捕获的 SyntaxError: 意外的 null 标记

同时,下面的代码可以成功运行,但我不建议在实际生活中这样做:

var undefined = 'bar'

这是因为在全局对象上 (window 对象在浏览器中运行的 JavaScript 中) 有一个 undefined 属性。

1
undefined='bar'并没有真正给undefined赋任何值(因为它是不可变的),它只是不清楚地不抛出错误。 - Dmitri Zaitsev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接