在javascript中,null 和undefined有什么区别?

What is the difference between null and undefined in JavaScript?

我想知道JavaScript中nullundefined之间的区别。


在javascript中,undefined表示变量已声明但尚未赋值,例如:

1
2
3
var TestVar;
alert(TestVar); //shows undefined
alert(typeof TestVar); //shows undefined

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

1
2
3
var TestVar = null;
alert(TestVar); //shows null
alert(typeof TestVar); //shows object

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

1
2
3
null === undefined // false
null == undefined // true
null === null // true

1
2
null = 'value' // ReferenceError
undefined = 'value' // 'value'


我从这里选的这个

The undefined value is a primitive value used when a variable has not
been assigned a value.

The null value is a primitive value that represents the null, empty,
or non-existent reference.

当您通过var声明一个变量并且不给它一个值时,它的值将是未定义的。如果您尝试wscript.echo()或alert()这个值,您将看不到任何内容。但是,如果在它后面附加一个空字符串,那么它会突然出现:

1
2
3
var s;
WScript.Echo(s);
WScript.Echo("" + s);

您可以声明一个变量,将其设置为空,并且行为是相同的,除了您将看到打印出的"空"和"未定义"之外。这确实是一个小小的区别。

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

1
2
undefined == null
null == undefined

然而,它们被认为是两种不同的类型。虽然undefined本身是一个类型all,但NULL被认为是一个特殊的对象值。通过使用type of()可以看到这一点,type of()返回一个表示变量常规类型的字符串:

1
2
3
4
var a;
WScript.Echo(typeof(a));
var b = null;
WScript.Echo(typeof(b));

运行上述脚本将导致以下输出:

1
2
undefined
object

不管它们是不同的类型,如果您试图访问其中一个成员,它们的行为仍然相同,例如,它们将抛出一个异常。有了wsh,你会看到可怕的"'varname'是空的或者不是一个对象",如果你很幸运的话(但这是另一篇文章的主题)。

您可以明确地将变量设置为未定义,但我强烈建议不要这样做。我建议只将变量设置为空,并为忘记设置的内容保留未定义的值。同时,我真的鼓励你总是设置每一个变量。JavaScript的作用域链不同于C风格的语言,即使是经验丰富的程序员也很容易混淆,将变量设置为空是防止基于它的错误的最佳方法。

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

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

上述脚本的结果是:

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

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

空值和未定义值的区别在于:javascript永远不会将任何内容设置为空值,这通常是我们要做的。虽然我们可以将变量设置为未定义,但我们更喜欢空值,因为它从来没有为我们做过。当您调试时,这意味着任何设置为空的东西都是您自己做的,而不是JavaScript。除此之外,这两个特殊值几乎相等。


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

把它当作一个价值,比如:

  • "foo"是字符串,
  • 真是布尔值,
  • 1234是数字,
  • 未定义空值。

Undefined属性表示还没有为变量分配包含空值的值。喜欢

1
var foo;

定义的空变量是undefined数据类型的null

它们都表示一个变量的值,但没有值

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

喜欢

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

现在如果

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

但是

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

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

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

空使用它来清空变量的值

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


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

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

JS可以用空值隐式初始化新声明的变量,但它不能。


请仔细阅读以下内容。它将消除你对在JavaScript中,空值和未定义值之间的差异。您还可以使用下面给出的实用程序函数来精确地确定类型。

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

  • 未声明的变量
  • 已声明但未分配的变量
  • 用未定义的文字指定的变量
  • 以文本空值分配的变量
  • 变量被分配了除未定义或空之外的任何内容
  • 下面逐一解释这些案例

  • 未声明的变量:对于未声明的变量,以下值为true

    • 只能由返回字符串"undefined"的typeof()检查
    • 不能用==或==或if或条件运算符检查?(引发引用错误)
  • 已声明但未分配的变量

    • typeof返回字符串"undefined"
    • ==检查为空返回真
    • ==用未定义的返回值检查为真
    • ===检查为空返回假
    • ===检查未定义的返回值为真
    • if或条件运算符?返回错误
  • 未定义字面赋值的变量:这些变量被视为已声明但未分配的变量。

  • 以文本空值分配的变量

    • typeof返回字符串"object"
    • ==检查为空返回真
    • ==用未定义的返回值检查为真
    • ===检查为空返回真
    • ===检查未定义的返回值为假
    • if或条件运算符?返回错误
  • 变量被赋予了除未定义或空之外的任何内容

    • typeof返回以下字符串之一:"string"、"number"、"boolean"、"function"、"object"、"symbol"
  • 下面提供了对变量进行正确类型检查的算法:

  • 使用typeof检查是否未声明/未分配/分配了未定义的。如果返回字符串"undefined",则返回。
  • 使用===检查是否为空。如果为真,则返回"null"。
  • 使用typeof检查实际类型。如果不等于"object",则返回类型
  • 调用object.prototype.toString.call(o)以确定实际的对象类型。对于所有内置的javascript或dom定义的对象,它应返回类型为'[object objecttype]'的字符串。对于用户定义的对象,它返回"[对象对象对象]"
  • 您还可以使用以下实用程序函数来确定类型。目前,它支持所有ECMA 262 2017类型。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    function TypeOf(o,bReturnConstructor)
     {
       if(typeof o==='undefined') return 'undefined'
       if(o===null) return 'null'  
       if(typeof o!=='object') return typeof o

       var type=Object.prototype.toString.call(o)
      switch(type)
      {
         //Value types:4
         case '[object Number]': type='number';break;
         case '[object String]': type='string';break;
         case '[object Boolean]': type='boolean';break;
         case '[object Date]': type='date';break;


       //Error Types:7
         case '[object Error]': type='error';break;
         case '[object EvalError]': type='evalerror';break;
         case '[object RangeError]': type='rangeerror';break;
         case '[object ReferenceError]': type='referenceerror';break;
         case '[object SyntaxError]': type='syntaxerror';break;
         case '[object TypeError]': type='typeerror';break;
         case '[object URIError]': type='urierror';break;


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

        //Keyed Collection Types:2
         case '[object Map]': type='map';break;
         case '[object WeakMap]': type='weakmap';break;

        //Set Types:2
         case '[object Set]': type='set';break;
         case '[object WeakSet]': type='weakset';break;

        //Operation Types
        case '[object RegExp]': type='regexp';break;
        case '[object Proxy]': type='proxy';break;
        case '[object Promise]': type='promise';break;

        case '[object Object]': type='object';
                 if(bReturnConstructor && o.constructor) type=o.constructor.toString().match(/^function\s*([^\s(]+)/)[1];
             break;
        default:
            type=type.split(' ')[1]
            type=type.substr(0,type.length-1)  

       }
        return type
    }

    我来解释一下undefinednullUncaught ReferenceError

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


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

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

    但相似之处到此为止。有一次,在实现关键字"空"和"未定义"的方式上存在根本区别。这并不明显,但请考虑以下示例:

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

    未定义,nan和infinity只是预初始化的"superglobal"变量的名称-它们在运行时初始化,可以被具有相同名称的普通全局或局部变量覆盖。

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

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

    哎呀!空、真和假是保留关键字-编译器不允许将它们用作变量或属性名。

    另一个区别是未定义是一个基元类型,而空是一个对象类型(表示对象引用的缺失)。考虑以下事项:

    1
    2
    3
    4
    5
    6
    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

    此外,在数字上下文中处理空值和未定义值的方式也有一个重要区别:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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 (!!!)

    当在算术表达式或数值比较中使用时,空值变为0—与false类似,它基本上只是一种特殊的"零"。另一方面,Undefined是一个真正的"Nothing",当您试图在数字上下文中使用它时,它会变成NaN("不是数字")。

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


    You might consider undefined to represent a system-level, unexpected, or error-like absence of value and null to represent program-level, normal, or expected absence of value.

    通过javascript:最终指南


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

    1
    2
    3
    var var1;
    alert(var1); //undefined
    alert(typeof var1); //undefined

    空是一个分配:

    1
    2
    3
    var var2= null;
    alert(var2); //null
    alert(typeof var2); //object


    DR

    使用null设置一个你知道是对象的变量。

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

    这是我对5个原语和对象类型的使用,这解释了它们之间的区别?用例?属于undefinednull

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

    1
    2
    3
    4
    ("") ? true : false; // false
    typeof""; //"string";
    ("Hello World") ? true : false; // true
    typeof"Hello World"; //"string"

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

    1
    2
    3
    4
    (0) ? true : false; // false
    typeof 0; //"number";
    (16) ? true : false; // true
    typeof 16; //"number"

    1
    2
    3
    4
    (NaN) ? true : false; // false
    typeof NaN; //"number";
    (16) ? true : false; // true
    typeof 16; //"number"

    布尔

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

    1
    2
    3
    4
    (false) ? true : false; // false
    typeof false; //"boolean";
    (true) ? true : false; // true
    typeof true; //"boolean"

    对象

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

    1
    2
    3
    4
    (null) ? true : false; // false
    typeof null; //"object";
    ({}) ? true : false; // true
    typeof {}; //"object"

    注:智能用法off NULL是对象的错误版本,因为对象总是true,并且因为typeof null返回object。这意味着typeof myVarObject返回对象和空类型的一致值。

    所有

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


    null是一个特殊值,意思是"无值"。null是一个特殊的对象,因为typeof null返回"object"。

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


    在javasscript中,有5种基本数据类型:string、number、boolean、null和undefined。我会用一些简单的例子来解释

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

    1
    2
    3
    4
    5
    6
    7
    8
     function test(a) {

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

    在上面的函数中,如果(a==null)与if(!a)

    现在,当我们在不传递参数a的情况下调用这个函数时

    1
    2
       test(); it will alert"a is null";
       test(4); it will alert"The value of a is" + 4;

    1
    2
    var a;
    alert(typeof a);

    这将给出未定义的;我们已经声明了一个变量,但没有为该变量指定任何值;但是如果我们写

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

    所以空值是一个对象。在某种程度上,我们为"a"赋值为空


    理解差异的最好方法是首先让您清楚地了解javascript的内部工作原理,并理解以下两者之间的含义差异:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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的问题是什么呢?

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

    1
    2
    let supervisor;
    assert(supervisor === undefined);
  • 一个从未设置过的对象的属性计算为undefined,因为没有人说过该属性。

    1
    2
    const dog = { name: 'Sparky', age: 2 };
    assert(dog.breed === undefined);
  • nullundefined彼此"相似",因为Brendan Eich这样说。但他们显然不平等。

    1
    2
    assert(null == undefined);
    assert(null !== undefined);
  • 幸好,nullundefined有不同的类型。null属于null型,undefined属于undefined型。这是规范,但你永远不会知道这是因为typeof的怪异,我不会在这里重复。

  • 如果函数到达其主体的末尾,但没有显式的返回语句,则返回undefined,因为您对返回的内容一无所知。

  • 顺便说一下,javascript中还有其他形式的"虚无"(学习哲学很好…)

    • NaN
    • 使用从未声明的变量并接收ReferenceError
    • 使用letconst在其时间死区中定义的局部变量并接收ReferenceError
    • 稀疏数组中的空单元格。是的,这些甚至不是undefined,尽管它们比较===和undefined。

      1
      2
      3
      4
      5
      6
      7
      $ node
      > const a = [1, undefined, 2]
      > const b = [1, , 2]
      > a
      [ 1, undefined, 2 ]
      > b
      [ 1, <1 empty item>, 2 ]

    好吧,当我们听到nullundefined的时候,我们可能会感到困惑,但让我们简单地说,它们在很多方面都是不可靠的,相似的,但在javascript中有一些奇怪的地方,使它们有一些显著的区别,例如,null的类型是'object',而undefined的类型是'undefined'

    1
    2
    typeof null; //"object"
    typeof undefined; //"undefined";

    但是如果你用下面的==检查它们,你会发现它们都是不稳定的:

    1
    null==undefined; //true

    也可以将null分配给对象属性或原语,而undefined只需不分配给任何内容即可实现。

    我创建了一个快速图像,让您一目了然地看到不同之处。

    Null and Undefined


    Both Null and undefined in JavaScript indicate absence of value.

    1
    2
    var a = null; //variable assigned null value
    var b;  // undefined

    Despite the fact both exist for absence of value but: Undefined
    actually means the variable is not initialized. Functions that return
    nothing and function parameters for which no value is supplied,
    undefined value is returned. Use strict equality operator === to
    distinguish between null and undefined.

    参考:http://www.thesstech.com/javascript/null-and-undefined


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

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

    因此,对于这两种类型,标签都是其类型和值。

    他们之间的区别。例如:

    • null为空值
    • undefined是一个缺少的值

    或:

    • undefined还没有值
    • null有一个值,不再有了

    实际上,null是一个特殊的关键字,而不是一个标识符,因此您不能将它当作一个变量来分配。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function foo() {
        undefined = 2; // bad idea!
    }

    foo();

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

    foo();

    空和未定义都用于表示缺少某个值。

    1
    var a = null;

    a已初始化并定义。

    1
    2
    typeof(a)
    //object

    空是javascript中的对象

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

    var b;

    B未定义且未初始化

    未定义的对象属性也未定义。例如,对象C上没有定义"x",如果您试图访问C.x,它将返回未定义。

    通常,我们将空值赋给未定义的变量。


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


    当您在javascript中声明一个变量时,它被赋予值undefined。这意味着变量是未触及的,可以在将来分配任何值。它还意味着您不知道这个变量在声明时要保存的值。

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

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


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

    未定义-它是一个变量,没有给它分配任何值,所以javascript会给它分配一个未定义的值(它是一个数据类型)。

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


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


    根据Ryan Morr关于这个问题的详细文章…

    "通常,如果需要为变量或属性分配非值、将其传递给函数或从函数返回非值,则空值几乎总是最佳选择。简单地说,javascript使用未定义的,程序员应该使用空值。"

    看探索永恒的无底深渊


    基本上,undefined是一个全局变量,JavaScript在运行时创建它,无论空值是否意味着没有给变量赋值(实际上空值本身就是一个对象)。

    让我们举个例子:

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

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

    现在,

    1
    2
    3
            x=5;
            y=null;
            z=x+y;

    你将得到5作为输出。这就是未定义和空值之间的主要区别


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

    未定义意味着变量在内存中有一个空间,但没有给它赋值。作为最佳实践,不应将此类型用作赋值。

    在这种情况下,如何在代码的后面一点表示您希望一个变量没有值的时间?你可以使用这个类型空,它也是一种类型,用于定义相同的东西,缺少值,但它与未定义的不同,因为在本例中,您实际上在内存中拥有值。该值为空

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


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

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

    空是一个对象。如果希望某个变量为空,则使用空。空变量存在,但值未知。应按语法将其分配给变量。空值不是自动初始化的。

    示例:var myname=null;console.log(typeof myname);检查CSOLE登录开发工具,它将是一个对象。


    只是添加我的视图-

    只有在编译语言如C++(或IDE中标记警告)的情况下,优化编译器才可删除仅声明且从不使用任何地方的变量。它最终意味着变量不存在,因为它的内存从未被分配。

    对于javascript解释器,[我猜]一个变量只有从它被赋予值的那一点开始才被视为存在。在这之前,它的类型是"未定义的",并且没有为它分配内存。所以它的类型是未定义的。

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


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