js 详解undefined与null

253 阅读2分钟

null

null是字面量、js关键字;

Object.getPrototypeOf(Object.prototype) // null;

typeof null === 'object'原因

null是机器代码空指针,在底层和对象类型标记一样,均为0x00, 所以typeof null === 'obejct'. // 这是一个被拒绝修改的bug. [2][3]

js初期代码

JS_PUBLIC_API(JSType)
    JS_TypeOfValue(JSContext *cx, jsval v)
    {
        JSType type = JSTYPE_VOID;
        JSObject *obj;
        JSObjectOps *ops;
        JSClass *clasp;
​
        CHECK_REQUEST(cx);
        if (JSVAL_IS_VOID(v)) {  // undefined(Void)
            type = JSTYPE_VOID;
        } else if (JSVAL_IS_OBJECT(v)) {  // 类型标记为对象(000:对象, 1:int, 010:double, 100:string, 110:boolean)
            obj = JSVAL_TO_OBJECT(v);
            if (obj &&
                (ops = obj->map->ops,
                 ops == &js_ObjectOps
                 ? (clasp = OBJ_GET_CLASS(cx, obj),
                    clasp->call || clasp == &js_FunctionClass)
                 : ops->call != 0)) { // 如果它是可调用的或者它的内部属性[[Class]]将它标记为函数 
                type = JSTYPE_FUNCTION; 
            } else { // 否则就是对象
                type = JSTYPE_OBJECT;
            }
        } else if (JSVAL_IS_NUMBER(v)) {
            type = JSTYPE_NUMBER;
        } else if (JSVAL_IS_STRING(v)) {
            type = JSTYPE_STRING;
        } else if (JSVAL_IS_BOOLEAN(v)) {
            type = JSTYPE_BOOLEAN;
        }
        return type;
    }

undefined [4]

  • 全局属性undefined表示原始值undefined;全局属性undefined是数据属性;如图

image-20221020112900689.png

  • undeined在局部环境下是能被修改的,如图; 所以value === undefined的判断是不可靠的,可以使用 void 0;void 0 [5] 返回全局属性undefined的值undefined,全局属性undefined不可修改和删除;

img

  • void通常只用于获取undefined的原始值,比如在箭头函数中避免泄漏 button.onClick = () => void doSomething(); // [4]

undefined与null对比

  • null一般表示定义了但为空,undefined一般表示从未赋值的自然状态;如图img
  • 非严格模式下,undefined == null

    ECMA11.9.3 章节中明确告诉我们:If x is null and y is undefined, return true.If x is undefined and y is null, return true.

undefined和null表现形式的区别

  • typeof: null => 'object', undefined => 'undefined';
  • Object.prototype.toString.call: null => '[object Null]', undefined => '[object undefined]';
   toString()是Object的原型方法,调用该方法,默认返回当前对象的[[Class]];

   Js中万物皆对象,为什么xxx.toString()不能返回变量类型?这是因为这个类中重写了toString方法;对于Object对象,直接调用toString()就能返回`[object Object]`.而对于其他对象,则需要通过call/apply来调用才能返回正确的类型信息;
  • null == undefined // true; null === undefined // false;
  • 转换成字符串: null => ‘null’, undeifned => "undefined";
  • 转换成布尔: null => false, undefined => false;
  • 转换成数值: null => 0, undefined => NaN;
  • json:
JSON.stringify({a: undefined}) // '{}'
JSON.stringify({b: null}) // '{b: null}'
JSON.stringify({a: undefined, b: null}) // '{b: null}'

相关资料

[1] 深入探究:null 和 undefined 究竟有何区别?

[2] typeof - JavaScript | MDN (mozilla.org)

[3] The history of “typeof null” (2ality.com)

[4] javascript中undefined的本质解析

[5] void 运算符 - JavaScript | MDN (mozilla.org)