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

我想知道JavaScript中nullundefined的区别。

593222 次浏览

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

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

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

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

从前面的例子中,很明显undefinednull是两个不同的类型:undefined是一个类型本身(未定义),而null是一个对象。

证明:

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 sideundefined = 'value' // 'value'

我把它从这里

未定义的值是一个原始值,当变量没有#36825;个值

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

当你通过var声明一个变量而不给它一个值时,它将具有未定义的值。单独地,如果你尝试WScript. Echo()或警报()此值,你将看不到任何内容。但是,如果你向其附加一个空字符串,那么它会突然出现:

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

您可以声明一个变量,将其设置为null,并且行为是相同的,除了您会看到“null”打印出来与“未定义”。这确实是一个很小的区别。

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

undefined == nullnull == undefined

然而,它们被认为是两种不同的类型。虽然未定义是一个完全属于自己的类型,但null被认为是一个特殊的对象值。您可以通过使用typeof()来看到这一点,它返回一个表示变量一般类型的字符串:

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

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

undefinedobject

不管它们是不同的类型,如果您尝试访问其中任何一个的成员,它们的行为仍然相同,例如,它们将抛出异常。使用WSH,您将看到可怕的“'varname'is null or not an Object”,这是如果您幸运的话(但这是另一篇文章的主题)。

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

另一个你会看到未定义弹出的实例是在使用删除运算符时。我们这些来自C世界的人可能会错误地将其解释为销毁对象,但事实并非如此。此操作的作用是从数组中删除下标或从对象中删除成员。对于数组,它不会影响长度,而是下标现在被认为是未定义的。

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

上述脚本的结果是:

0.) a1.) undefined2.) c

当读取从未存在的下标或成员时,您也会得到未定义的返回。

null和untex的区别是:JavaScript永远不会将任何内容设置为null,这通常是我们所做的。虽然我们可以将变量设置为untex,但我们更喜欢null,因为它不是为我们完成的。当你调试时,这意味着任何设置为null的东西都是你自己做的,而不是JavaScript。除此之外,这两个特殊值几乎是等价的。

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

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

Null是一个赋值:

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

null是一个特殊值,表示“没有值”。null是一个特殊对象,因为typeof null返回“对象”。

另一方面,undefined意味着变量没有被声明,或者没有被赋予值。

null:没有变量的值;未定义:没有变量本身;

…其中变量是与值关联的符号名称。

JS可以用null隐式初始化新声明的变量,但它没有。

由于typeof返回未定义,undefault是一个类型,其中null是一个初始化器,表示变量不指向任何对象(Javascript中的几乎所有内容都是对象)。

null和un憎恨都是用来表示某个值的缺失。

var a = null;

a被初始化和定义。

typeof(a)//object

null是JavaScript中的一个对象

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

b未定义且未初始化

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

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

null是一个特殊的关键字,表示没有值。

把它看作一个值,比如:

  • "foo"是字符串,
  • true是boolean,
  • 1234是数字。
  • null未定义。

未定义属性表示尚未为变量分配包括null在内的值。喜欢

var foo;

定义的空变量是数据类型undefinednull


两者都代表一个没有值的变量的值

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


喜欢

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

现在如果

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

但是

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

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

未定义使用它来比较变量数据类型

null使用它来清空变量的值

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

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

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

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

此外,上面的function 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);

这将给出undefault;我们已经声明了一个变量,但我们没有为这个变量分配任何值;

但如果我们写

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

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

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

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

然而,相似之处到此结束。这一次,关键字null未定义的实现方式存在根本差异。这并不明显,但考虑以下示例:

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

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

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

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

null真正虚假是保留关键字-编译器不允许您将它们用作变量或属性名称

另一个区别是未定义是基本类型,而null是对象类型(表示对象引用的缺失)。考虑以下内容:

WScript.Echo(typeof false); // Will print: booleanWScript.Echo(typeof 0); // Will print: numberWScript.Echo(typeof ""); // Will print: stringWScript.Echo(typeof {}); // Will print: objectWScript.Echo(typeof undefined); // Will print: undefinedWScript.Echo(typeof null); // (!!!) Will print: object

此外,在数字上下文中处理null未定义的方式存在重要差异:

var a; // declared but uninitialized variables hold the value undefinedWScript.Echo(a === undefined); // Prints: -1
var b = null; // the value null must be explicitly assignedWScript.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变成了——与虚假类似,它基本上只是一种特殊的“零”。另一方面,未定义是一个真正的“无”,当你尝试在数字上下文中使用它时,它变成了NaN(“不是数字”)。

请注意,null未定义接受==!=运算符的特殊处理,但您可以使用表达式(a >= b && a <= b)测试一个b的真正数字相等性。

您可能会认为untex表示系统级、意外或类似错误的值缺失,而null表示程序级、正常或预期的值缺失。

通过JavaScript:权威指南

补充一下我的观点——

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

在javascript解释器的情况下,[我猜]一个变量仅从它被赋予值的那一刻起被视为存在。在那之前,它的类型是“未定义的”,没有为它分配内存。而且,所以它的类型是未定义的。

javascript中的null表示一个地址的值,但该地址还没有指向任何东西[不存在的引用]。尽管如此,它还是一个值。

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

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

未定义-它是一个没有分配任何值的变量,因此JavaScript会为其分配一个unset(它是一种数据类型)。

未申报-如果一个变量根本没有创建,它被称为未声明。

如果一个变量没有初始化,那么它是未定义的。未定义不是对象。示例:var MyName;console.log(typeof MyName);

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

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

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

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

根据Ryan Morr关于这个主题的详尽文章…

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

探索空与未定义的永恒深渊

对于undefined类型,只有一个值:undefined

对于null类型,只有一个值:null

对于他们俩来说,标签既是它的类型,也是它的值。

它们之间的区别。例如:

  • null是一个空值
  • undefined是一个缺失值

或:

  • undefined还没有值
  • null有一个值,现在没有了

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

然而,undefined是一个标识符。然而,在non-strict模式和strict模式下,您可以创建一个名称未定义的局部变量。但这是一个可怕的想法!

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

我将解释undefinednullUncaught ReferenceError

1-Uncaught ReferenceError:脚本中的变量尚未宣布,没有引用此变量
2-undefined:变量声明但未初始化
3-null:变量声明为空值

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

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

  1. 未声明的变量
  2. 声明但未赋值的变量
  3. 使用文字undefined分配的变量
  4. 使用文字null分配的变量
  5. 变量赋值为undefinednull以外的任何值

以下将逐一解释这些案例:

  1. 未声明的变量

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

    • typeof返回字符串“不确定”
    • ==检查null返回true
    • ==检查undefined返回true
    • ===检查null返回false
    • ===检查undefined返回true
    • Falsyif语句三元运算符? :
  3. 使用文字#0分配的变量
    这些变量的处理方式与声明但未赋值的变量完全相同。

  4. 使用文字#0分配的变量

    • typeof返回字符串对象
    • ==检查null返回true
    • ==检查undefined返回true
    • ===检查null返回true
    • ===检查undefined返回false
    • Falsyif语句三元运算符? :
  5. 变量赋值为#0或#1以外的任何值

    • typeof返回以下字符串之一:“大”布尔型函数数字对象字符串符号

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

  1. 获取我们的变量typeof,如果不是对象则返回它
  2. 检查null,因为typeof null也返回对象
  3. 使用Switch语句评估Object.prototype.toString.call(o)以返回更精确的值。ObjecttoString方法返回的字符串看起来像本机/主机对象的'[对象构造器名称]'。对于所有其他对象(用户定义的对象),它总是返回'[对象对象]'
  4. 如果最后一部分是这种情况(变量的字符串化版本是'[对象对象]')并且参数返回构造函数Booleantrue,它将尝试通过toString读取它并从那里提取名称来获取构造函数的名称。如果无法到达构造函数,则像往常一样返回对象。如果字符串不包含其名称,则返回匿名

(支持ECMAScript 2020之前的所有类型)

function TypeOf(o, returnConstructorBoolean) {const type = typeof o
if (type !== 'object') return typeif (o === null)        return 'null'
const toString = Object.prototype.toString.call(o)
switch (toString) {// Value types: 6case '[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: 7case '[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: 13case '[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: 2case '[object Map]':               return 'map'case '[object WeakMap]':           return 'weakmap'
// Set types: 2case '[object Set]':               return 'set'case '[object WeakSet]':           return 'weakset'
// Operation types: 3case '[object RegExp]':            return 'regexp'case '[object Proxy]':             return 'proxy'case '[object Promise]':           return 'promise'
// Plain objectscase '[object Object]':if (!returnConstructorBoolean)return type
const _prototype = Object.getPrototypeOf(o)if (!_prototype)return type
const _constructor = _prototype.constructorif (!_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)}}

基本上,未定义是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个原语和Object类型的用法,这解释了undefinednull的“用例”之间的区别。

String

如果您知道一个变量只是一个字符串,而所有生命周期,按照惯例,您可以将其初始化为""

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

数量

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

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

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

布尔

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

(false) ? true : false; // falsetypeof false; // "boolean";(true) ? true : false; // truetypeof true; // "boolean"

对象

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

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

注意:关闭null的聪明用法是Object的false sy版本,因为Object总是true,并且typeof null返回object。这意味着typeof myVarObject为Object和null类型返回一致的值。

所有

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

好吧,当我们听到nullundefined时,我们可能会感到困惑,但让我们简单地开始,它们都是Falsy,并且在许多方面相似,但是JavaScript的奇怪部分,使它们有几个显着的差异,例如,typeofnull'object',而typeofundefined'undefined'

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

但是如果你用下面的==检查它们,你会发现它们都是Falsy

null==undefined; //true

您还可以将null赋值给对象属性或原语,而undefined可以简单地通过不赋值给任何东西来实现。

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

空且未定义

当您在javascript中声明一个变量时,它会被分配值undefined。这意味着该变量未被触及,将来可以分配任何值。这也意味着您不知道该变量在声明时将持有的值。

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

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

理解差异的最佳方法是首先清除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. A property of an object that has never been set evaluates to undefined because no one ever said anything about that property.

    const dog = { name: 'Sparky', age: 2 };assert(dog.breed === undefined);
  3. null and undefined are "similar" to each other because Brendan Eich said so. But they are emphatically not equal to each other.

    assert(null == undefined);assert(null !== undefined);
  4. null and undefined thankfully have different types. null belongs to the type Null and undefined to the type Undefined. This is in the spec, but you would never know this because of the typeof weirdness which I will not repeat here.

  5. A function reaching the end of its body without an explicit return statement returns undefined since you don't know anything about what it returned.

By the way, there are other forms of "nothingness" in JavaScript (it's good to have studied Philosophy....)

  • NaN
  • Using a variable that has never been declared and receiving a ReferenceError
  • Using a let or const defined local variable in its temporal dead zone and receiving a ReferenceError
  • Empty cells in sparse arrays. Yes these are not even undefined although they compare === to undefined.

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

我想添加一个与null未定义之间的细微差异有关的知识点。当您尝试从头开始学习Vanilla JavaScript(JS)时,这是很好的了解:

null是JS中的保留关键字,而未定义是JS中的属性您所在运行时环境的全局对象。

在编写代码时,这种差异是无法识别的,因为null未定义总是在JavaScript语句的右侧(RHS)中使用。但是当你在表达式的左侧(LHS)中使用它们时,你可以很容易地观察到这种差异。所以JS解释器将以下代码解释为错误:

var null = 'foo'

它给出了以下错误:

未捕获的语法错误:意外的令牌null

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

var undefined = 'bar'

这是有效的,因为未定义是全局对象的属性(在浏览器中运行JavaScript的情况下为窗口对象)

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

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

  • 零值就像一个空厕所纸巾管的支架。

  • 空值就像一个甚至没有组织管的保持器。

  • 未定义的值类似于持有人本身丢失。

两个特殊值都暗示一个空状态。

主要区别在于未定义表示尚未初始化的变量的值,而null表示对象的故意缺失。

变量数字是定义的,但是,没有分配初始值:

let number;number; // => undefined

数字变量是未定义的,这清楚地表明一个未初始化的变量

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

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

因为lastName属性在obj中不存在,所以JavaScript正确地将obj.lastName计算为未定义。

在其他情况下,您知道变量期望保存一个对象或一个函数来返回一个对象。但是由于某种原因,您无法实例化该对象。在这种情况下,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);             // => nullclone(null);           // => null

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

typeof运算符区分了两个值:

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

严格的质量运算符===正确地区分未定义和null:

let nothing = undefined;let missingObject = null;nothing === missingObject; // => false

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

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. 对象解构对这两个值的工作方式不同:
    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"

引用Marijn Haverbeke的“Eloquent Javascript”第三版:

undefinednull之间的含义差异是JavaScript设计的意外,在大多数情况下并不重要。在您实际上必须关心这些值的情况下,我建议将它们视为基本上可互换的

老实说,起初,我对这个建议有点怀疑。然而,在我自己的解释中,这是一种lazy(vseager)的方式来处理他们的差异。也许,我们根本不需要处理这些差异。如果必须,我们可以推迟我们的关注(直到我们必须这样做),而不是hyperactively/defensively担心它,因为这些值(nullundefined)流经我们的代码。

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

在Javascript中,null是一个空的或不存在的值,必须分配它。但未定义意味着变量已声明,但值尚未定义。

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

在JS中,空值和未定义都是原始值。您还可以查看以下代码行

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

未定义和null之间的含义差异是JavaScript设计的意外,在大多数情况下并不重要。在您实际上必须关心这些值的情况下,我建议将它们视为基本上可互换的。

雄辩的Javascript的书

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

typeof undefined; //undefinedtypeof null; // Objectundefined !== null; //trueundefined == null; //trueundefined === null; //falsevar var1;var1; //undefinedvar var2 = null;var2; //null

已经给出了很多“技术”答案,从JS仅仅是一种编程语言的有限角度来看,它们大多是正确的。

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

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

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

以下是使其成为可能的指导方针:

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

不要使用null来避免混淆。

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

尽管如此,如果框架使用它,或者用于json序列化,null还是有意义的。

const data  = { banners: null }const { banners = [] } = data;console.log(data)      // null

const data  = { banners: undefined }const { banners = [] } = data;console.log(data)      // []