我想知道JavaScript中null和undefined之间的区别。


当前回答

理解差异的最佳方法是首先理清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用两个不同的值(null和undefined)来区分后两种情况。您可以自由地明确使用这些值来表达这些含义。

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

没有初始值设定项的已声明变量将获得未定义的值,因为您从未说过预期值是什么。出租监督员;断言(主管==未定义);从未设置过的对象的属性求值为undefined,因为没有人说过该属性。const dog={name:“Sparky”,年龄:2};断言(dog.bred==未定义);null和undefined彼此“相似”,因为Brendan Eich是这么说的。但它们显然彼此不相等。断言(null==未定义);断言(null!==未定义);谢天谢地,null和undefined有不同的类型。null属于null类型,undefined属于undefined类型。这在规范中,但你永远不会知道这一点,因为我不会在这里重复这种奇怪的类型。如果函数到达其主体的末尾而没有显式返回语句,则返回undefined,因为您不知道它返回了什么。

顺便说一句,JavaScript中还有其他形式的“虚无”(学习哲学很好……)

NaN公司使用从未声明的变量并接收ReferenceError在其时间死区中使用let或const定义的局部变量并接收ReferenceError稀疏数组中的空单元格。是的,虽然它们与undefined相比==,但它们甚至没有定义。$节点>常量a=[1,未定义,2]>常量b=[1,2]>一个[1,未定义,2]>b级[1,<1空项>,2]

其他回答

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

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

var测试var;console.log(testVar)//显示未定义console.log(testVar类型)//显示未定义

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

var testVar=空;console.log(testVar)//显示nullconsole.log(testVar类型)//显示对象

从前面的示例中可以清楚地看到,undefined和null是两种不同的类型:undefineed是类型本身(undefine),而null是对象。

证明:

console.log(null==未定义)//false(类型不同)console.log(null==undefined)//true(但为“相同值”)console.log(null==null)//true(类型和值相同)

and

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

tl;博士

使用null设置一个已知为Object的变量。

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


这是我对5个原语和Object类型的用法,这解释了未定义或空的«用例»之间的区别。

一串

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

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

数字

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

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

or

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

对象

如果您知道一个变量在所有生命周期中都只是一个Object,那么按照惯例,您可以将其初始化为null:

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

注意:关闭null的智能用法是Object的错误版本,因为Object始终为true,因为typeof null返回对象。这意味着typeof myVarObject返回Object和null类型的一致值。

All

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

看看这个。输出值一千字。

var b1=文档.getElementById(“b1”);checkif(“1,无参数”);checkif(“2,显式未定义”,未定义);checkif(“3,显式空”,空);checkif(“4,the 0”,0);checkif(“5,空字符串”,“”);checkif(“6,string”,“string”);checkif(“7,number”,123456);函数checkif(a1,a2){print(“\ncheckif(),”+a1+“:”);如果(a2==未定义){打印(“==未定义:是”);}其他{打印(“==未定义:否”);}如果(a2==未定义){打印(“==未定义:是”);}其他{打印(“==未定义:否”);}如果(a2==空){打印(“==null:YES”);}其他{打印(“==null:NO”);}如果(a2==空){打印(“==空:是”);}其他{打印(“==null:NO”);}如果(a2==“”){打印(“=='':是”);}其他{打印(“=='':否”);}如果(a2==“”){打印(“=='':是”);}其他{打印(“=='':否”);}如果(isNaN(a2)){打印(“isNaN():是”);}其他{打印(“isNaN():否”);}如果(a2){打印(“如果-?:是”);}其他{打印(“如果-?:否”);}打印(“typeof():”+typeof(a2));}函数打印(v){b1.innerHTML+=v+“\n”;}<!DOCTYPE html><html><body><pre id=“b1”></pre></body></html>

另请参见:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefinedhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaNhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/nullhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators

干杯

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

两者都只能保存一个值,分别为null和undefined;两者都没有财产或方法,尝试读取其中一个的任何财产都会导致运行时错误(对于所有其他对象,如果尝试读取不存在的属性,则会得到未定义的值);通过==和!=,值null和undefined被视为彼此相等,其他值都不相等操作员。

然而,相似之处到此为止。这一次,在实现关键字null和undefined的方式上有一个根本的区别。这并不明显,但请考虑以下示例:

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

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

现在,让我们对null做同样的尝试:

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

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

另一个区别是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

此外,在数字上下文中处理null和undefined的方式也有一个重要的区别:

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时,null变为0-与false类似,它基本上只是一种特殊的“零”。另一方面,undefined是一个真正的“无”,当您尝试在数字上下文中使用它时,它会变成NaN(“非数字”)。

注意,null和undefined从==和!=接收特殊处理运算符,但可以使用表达式(a>=b&&a<=b)测试a和b的真正数值相等性。