What is the difference between null and undefined in JavaScript?

前端 未结 30 3256
夕颜
夕颜 2020-11-21 23:06

I want to know what the difference is between null and undefined in JavaScript.

相关标签:
30条回答
  • 2020-11-21 23:43

    The best way to understand the difference is to first clear your mind of the inner workings of JavaScript and just understand the differences in meaning between:

    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.
    

    There is a difference in meaning between these three cases, and JavaScript distinguishes the latter two cases with two different values, null and undefined. You are free to use those values explicitly to convey those meanings.

    So what are some of the JavaScript-specific issues that arise due to this philosophical basis?

    1. A declared variable without an initializer gets the value undefined because you never said anything about the what the intended value was.

      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 ]
      
    0 讨论(0)
  • 2020-11-21 23:44

    Both special values imply an empty state.

    The main difference is that undefined represents the value of a variable that wasn’t yet initialized, while null represents an intentional absence of an object.

    The variable number is defined, however, is not assigned with an initial value:

    let number;
    number; // => undefined
    

    number variable is undefined, which clearly indicates an uninitialized variable

    The same uninitialized concept happens when a non-existing object property is accessed:

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

    Because lastName property does not exist in obj, JavaScript correctly evaluates obj.lastName to undefined.

    In other cases, you know that a variable expects to hold an object or a function to return an object. But for some reason, you can’t instantiate the object. In such a case null is a meaningful indicator of a missing object.

    For example, clone() is a function that clones a plain JavaScript object. The function is expected to return an object:

    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
    

    However, clone() might be invoked with a non-object argument: 15 or null (or generally a primitive value, null or undefined). In such case, the function cannot create a clone, so it returns null - the indicator of a missing object.

    typeof operator makes the distinction between the two values:

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

    The strict quality operator === correctly differentiates undefined from null:

    let nothing = undefined;
    let missingObject = null;
    nothing === missingObject; // => false
    
    0 讨论(0)
  • 2020-11-21 23:46

    null: absence of value for a variable; undefined: absence of variable itself;

    ..where variable is a symbolic name associated with a value.

    JS could be kind enough to implicitly init newly declared variables with null, but it does not.

    0 讨论(0)
  • 2020-11-21 23:47

    null and undefined are two distinct object types which have the following in common:

    • both can only hold a single value, null and undefined respectively;
    • both have no properties or methods and an attempt to read any properties of either will result in a run-time error (for all other objects, you get value undefined if you try to read a non-existent property);
    • values null and undefined are considered equal to each other and to nothing else by == and != operators.

    The similarities however end here. For once, there is a fundamental difference in the way how keywords null and undefined are implemented. This is not obvious, but consider the following example:

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

    undefined, NaN and Infinity are just names of preinitialized "superglobal" variables - they are initialized at run-time and can be overridden by normal global or local variable with the same names.

    Now, let's try the same thing with null:

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

    Oops! null, true and false are reserved keywords - compiler won't let you use them as variable or property names

    Another difference is that undefined is a primitive type, while null is an object type (indicating the absense of an object reference). Consider the following:

    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
    

    Also, there is an important difference in the way null and undefined are treated in numeric context:

    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 becomes 0 when used in arithmetic expressions or numeric comparisons - similarly to false, it is basically just a special kind of "zero". undefined, on the other hand, is a true "nothing" and becomes NaN ("not a number") when you try to use it in numeric context.

    Note that null and undefined receive a special treatment from == and != operators, but you can test true numeric equality of a and b with the expression (a >= b && a <= b).

    0 讨论(0)
  • 2020-11-21 23:50

    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.

    via JavaScript:The Definitive Guide

    0 讨论(0)
  • 2020-11-21 23:51

    Undefined means a variable has been declared but has no value:

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

    Null is an assignment:

    var var2= null;
    alert(var2); //null
    alert(typeof var2); //object
    
    0 讨论(0)
提交回复
热议问题