Why is null an object and what's the difference between null and undefined?

后端 未结 22 1060
猫巷女王i
猫巷女王i 2020-11-22 02:58

Why is null considered an object in JavaScript?

Is checking

if ( object == null )
      Do something

the

相关标签:
22条回答
  • 2020-11-22 03:37

    One way to make sense of null and undefined is to understand where each occurs.

    Expect a null return value in the following situations:

    • Methods that query the DOM

      console.log(window.document.getElementById("nonExistentElement"));
      //Prints: null
      
    • JSON responses received from an Ajax request

    
        {
          name: "Bob",
          address: null
        }
    
    • RegEx.exec.

    • New functionality that is in a state of flux. The following returns null:

    
            var proto = Object.getPrototypeOf(Object.getPrototypeOf({}));
    
           // But this returns undefined:
    
            Object.getOwnPropertyDescriptor({}, "a");
    

    All other cases of non-existence are denoted by undefined (as noted by @Axel). Each of the following prints "undefined":

        var uninitalised;
        console.log(uninitalised);
    
        var obj = {};
        console.log(obj.nonExistent);
    
        function missingParam(missing){
            console.log(missing);
        }
    
        missingParam();
    
        var arr = [];
        console.log(arr.pop());        
    

    Of course if you decide to write var unitialised = null; or return null from a method yourself then you have null occurring in other situations. But that should be pretty obvious.

    A third case is when you want to access a variable but you don't even know if it has been declared. For that case use typeof to avoid a reference error:

    if(typeof unknown !== "undefined"){
        //use unknown
    }
    

    In summary check for null when you are manipulating the DOM, dealing with Ajax, or using certain ECMAScript 5 features. For all other cases it is safe to check for undefined with strict equality:

    if(value === undefined){
      // stuff
    }
    
    0 讨论(0)
  • 2020-11-22 03:39

    From "The Principles of Object-Oriented Javascript" by Nicholas C. Zakas

    But why an object when the type is null? (In fact, this has been acknowledged as an error by TC39, the committee that designs and maintains JavaScript. You could reason that null is an empty object pointer, making "object" a logical return value, but that’s still confusing.)

    Zakas, Nicholas C. (2014-02-07). The Principles of Object-Oriented JavaScript (Kindle Locations 226-227). No Starch Press. Kindle Edition.

    That said:

    var game = null; //typeof(game) is "object"
    
    game.score = 100;//null is not an object, what the heck!?
    game instanceof Object; //false, so it's not an instance but it's type is object
    //let's make this primitive variable an object;
    game = {}; 
    typeof(game);//it is an object
    game instanceof Object; //true, yay!!!
    game.score = 100;
    

    Undefined case:

    var score; //at this point 'score' is undefined
    typeof(score); //'undefined'
    var score.player = "felix"; //'undefined' is not an object
    score instanceof Object; //false, oh I already knew that.
    
    0 讨论(0)
  • 2020-11-22 03:39

    TLDR

    undefined is a primitive value in JavaScript that indicates the implicit absence of a value. Uninitialized variables automatically have this value, and functions without an explicit return statement, return undefined.

    null is also a primitive value in JavaScript. It indicates the intentional absence of an object value. null in JavaScript was designed to enable interoperability with Java.

    typeof null returns "object" because of a peculiarity in the design of the language, stemming from the demand that JavaScript be interoperable with Java. It does not mean null is an instance of an object. It means: given the tree of primitive types in JavaScript, null is part of the "object-type primitive" subtree. This is explained more fully below.

    Details

    undefined is a primitive value that represents the implicit absence of a value. Note that undefined was not directly accessible until JavaScript 1.3 in 1998. This tells us that null was intended to be the value used by programmers when explicitly indicating the absence of a value. Uninitialized variables automatically have the value undefined. undefined is a one-of-a-kind type in the ECMAScript specification.

    null is a primitive value that represents the intentional absence of an object value. null is also a one-of-a-kind type in the ECMAScript specification.

    null in JavaScript was designed with a view to enable interoperability with Java, both from a "look" perspective, and from a programatic perspective (eg the LiveConnect Java/JS bridge planned for 1996). Both Brendan Eich and others have since expressed distaste at the inclusion of two "absence of value" values, but in 1995 Eich was under orders to "make [JavaScript] look like Java".

    Brendan Eich:

    If I didn't have "Make it look like Java" as an order from management, and I had more time (hard to unconfound these two causal factors), then I would have preferred a Self-like "everything's an object" approach: no Boolean, Number, String wrappers. No undefined and null. Sigh.

    In order to accommodate Java's concept of null which, due to the strongly-typed nature of Java, can only be assigned to variables typed to a reference type (rather primitives), Eich chose to position the special null value at the top of the object prototype chain (ie. the top of the reference types), and to include the null type as part of the set of "object-type primitives".

    The typeof operator was added shortly thereafter in JavaScript 1.1, released on 19th August 1996.

    From the V8 blog:

    typeof null returns object, and not null, despite null being a type of its own. To understand why, consider that the set of all JavaScript types is divided into two groups:

    1. objects (i.e. the Object type)
    2. primitives (i.e. any non-object value)

    As such, null means “no object value”, whereas undefined means “no value”.

    Following this line of thought, Brendan Eich designed JavaScript to make typeof return 'object' for all values on the right-hand side, i.e. all objects and null values, in the spirit of Java. That’s why typeof null === 'object' despite the spec having a separate null type.

    So Eich designed the heirarchy of primitive types to enable interoperability with Java. This led to him positioning null along with the "object-type primitives" on the heirarchy. To refelct this, when typeof was added to the language shortly thereafter, he chose typeof null to return "object".

    The surprise expressed by JavaScript developers at typeof null === "object" is the result of an impedance mismatch (or abstraction leak) between a weakly-typed language (JavaScript) that has both null and undefined, and another, strongly-typed language (Java) that only has null, and in which null is strictly defined to refer to a reference type (not a primitive type).

    Note that this is all logical, reasonable and defensible. typeof null === "object" is not a bug, but a second-order effect of having to accommodate Java interoperability.

    A number of imperfect backwards rationalisations and/or conventions have emerged, including that undefined indicates implicit absence of a value, and that null indicates intentional absence of a value; or that undefined is the absence of a value, and null is specifically the absence of an object value.

    A relevant conversation with Brendan Eich, screenshotted for posterity:

    0 讨论(0)
  • 2020-11-22 03:40
    typeof null;      // object
    typeof undefined; // undefined
    

    The value null represents the intentional absence of any object value. It is one of JavaScript's primitive values and is treated as falsy for boolean operations.

    var x = null;
    var y;
    

    x is declared & defined as null

    y is declared but not defined. It is declared with no value so it is undefined.

    z is not declared so would also be undefined if you attempted to use z.

    0 讨论(0)
  • 2020-11-22 03:46
    1. Undefined means a variable has been declared but it has not been assigned any value while Null can be assigned to a variable representing "no value".(Null is an assignment operator)

    2.Undefined is a type itself while Null is an object.

    3.Javascript can itself initialize any unassigned variable to undefined but it can never set value of a variable to null. This has to be done programatically.

    0 讨论(0)
  • 2020-11-22 03:50

    null is not an object, it is a primitive value. For example, you cannot add properties to it. Sometimes people wrongly assume that it is an object, because typeof null returns "object". But that is actually a bug (that might even be fixed in ECMAScript 6).

    The difference between null and undefined is as follows:

    • undefined: used by JavaScript and means “no value”. Uninitialized variables, missing parameters and unknown variables have that value.

      > var noValueYet;
      > console.log(noValueYet);
      undefined
      
      > function foo(x) { console.log(x) }
      > foo()
      undefined
      
      > var obj = {};
      > console.log(obj.unknownProperty)
      undefined
      

      Accessing unknown variables, however, produces an exception:

      > unknownVariable
      ReferenceError: unknownVariable is not defined
      
    • null: used by programmers to indicate “no value”, e.g. as a parameter to a function.

    Examining a variable:

    console.log(typeof unknownVariable === "undefined"); // true
    
    var foo;
    console.log(typeof foo === "undefined"); // true
    console.log(foo === undefined); // true
    
    var bar = null;
    console.log(bar === null); // true
    

    As a general rule, you should always use === and never == in JavaScript (== performs all kinds of conversions that can produce unexpected results). The check x == null is an edge case, because it works for both null and undefined:

    > null == null
    true
    > undefined == null
    true
    

    A common way of checking whether a variable has a value is to convert it to boolean and see whether it is true. That conversion is performed by the if statement and the boolean operator ! (“not”).

    function foo(param) {
        if (param) {
            // ...
        }
    }
    function foo(param) {
        if (! param) param = "abc";
    }
    function foo(param) {
        // || returns first operand that can't be converted to false
        param = param || "abc";
    }
    

    Drawback of this approach: All of the following values evaluate to false, so you have to be careful (e.g., the above checks can’t distinguish between undefined and 0).

    • undefined, null
    • Booleans: false
    • Numbers: +0, -0, NaN
    • Strings: ""

    You can test the conversion to boolean by using Boolean as a function (normally it is a constructor, to be used with new):

    > Boolean(null)
    false
    > Boolean("")
    false
    > Boolean(3-3)
    false
    > Boolean({})
    true
    > Boolean([])
    true
    
    0 讨论(0)
提交回复
热议问题