test undefined和NULL的区别

理解null与undefined
本文深入探讨了JavaScript中null与undefined的区别及应用场景,分析了两者在内存中的表现形式,并解释了为何两者在使用相等操作符时会被视为相等。

最近在看《JavaScript高级程序设计》一书,书中讲到相等操作符(==)时说,要比较相等性之前,不能将 null 和 undefined 转换成其他任何值,但要记住 null == undefined 会返回 true 。的确,在ECMAScript规范中也是这样定义的,但我认为这样来理解这件事情,似乎有些浮于表面,网上也有很多关于这个问题的文章,下面我希望从一个全新的角度来分析 null 和 undefined 的区别,从而理解两者为何会相等:

 

Undefined 和 Null 是 Javascript 中两种特殊的原始数据类型(Primary Type),它们都只有一个值,分别对应 undefined 和 null ,这两种不同类型的值,即有着不同的语义和场景,但又表现出较为相似的行为:

 

1、undefined

 

undefined 的字面意思就是未定义的值,这个值的语义是,希望表示一个变量最原始的状态,而非人为操作的结果 。 这种原始状态会在以下 4 种场景中出现:

 

【1】声明了一个变量,但没有赋值

 

var foo;

console.log(foo); //undefined

 

访问foo,返回了undefined,表示这个变量自从声明了以后,就从来没有使用过,也没有定义过任何有效的值,即处于一种原始而不可用的状态。

 

【2】访问对象上不存在的属性

 

console.log(Object.foo); // undefined

 

访问Object对象上的 foo 属性,同样也返回 undefined , 表示Object 上不存在或者没有定义名为 “foo” 的属性。

 

【3】函数定义了形参,但没有传递实参

 

//函数定义了形参 a

function fn(a) {

    console.log(a); //undefined

}

fn(); //未传递实参

 

函数 fn 定义了形参a, 但 fn 被调用时没有传递参数,因此,fn 运行时的参数 a 就是一个原始的、未被赋值的变量。

 

【4】使用 void 对表达式求值

 

void 0 ; // undefined

void false; //undefined

void []; //undefined

void null; //undefined

void function fn(){} ; //undefined

 

ECMAScript 规范 void 操作符 对任何表达式求值都返回 undefined ,这个和函数执行操作后没有返回值的作用是一样的,JavaScript中的函数都有返回值,当没有 return 操作时,就默认返回一个原始的状态值,这个值就是undefined,表明函数的返回值未被定义。

 

因此,undefined 一般都来自于某个表达式最原始的状态值,不是人为操作的结果。当然,你也可以手动给一个变量赋值 undefined,但这样做没有意义,因为一个变量不赋值就是 undefined 。

 

2、null

 

null 的字面意思是 空值 ,这个值的语义是,希望表示 一个对象被人为的重置为空对象,而非一个变量最原始的状态 。 在内存里的表示就是,栈中的变量没有指向堆中的内存对象,即:

 

 

 

当一个对象被赋值了null 以后,原来的对象在内存中就处于游离状态,GC 会择机回收该对象并释放内存。因此,如果需要释放某个对象,就将变量设置为null,即表示该对象已经被清空,目前无效状态。试想一下,如果此处把 null 换成 undefined 会不会感到别扭? 显然语义不通,其操作不能正确的表达其想要的行为。

 

与 null 相关的另外一个问题需要解释一下:

 

typeof null == 'object'  

 

null 有属于自己的类型 Null,而不属于Object类型,typeof 之所以会判定为 Object 类型,是因为JavaScript 数据类型在底层都是以二进制的形式表示的,二进制的前三位为 0 会被 typeof 判断为对象类型,而 null 的二进制位恰好都是 0 ,因此,null 被误判断为 Object 类型。

 

  • 000 – 对象,数据是对象的应用

  • 1 – 整型,数据是31位带符号整数

  • 010 – 双精度类型,数据是双精度数字

  • 100 – 字符串,数据是字符串

  • 110 – 布尔类型,数据是布尔值

 

其实,我们可以通过另一种方法获取 null 的真实类型:

 

Object.prototype.toString.call(null) ; // [object Null]

 

通过 Object 原型上的toString() 方法可以获取到JavaScript 中对象的真实数据类型,当然 undefined 类型也可以通过这种方式来获取:

 

Object.prototype.toString.call(undefined) ; // [object Undefined]

 

3、相似性

 

虽然 undefined 和 null 的语义和场景不同,但总而言之,它们都表示的是一个无效的值。 因此,在JS中对这类值访问属性时,都会得到异常的结果:

 

 

 

ECMAScript 规范认为,既然 null 和  undefined 的行为很相似,并且都表示 一个无效的值,那么它们所表示的内容也具有相似性,即有

 

undefined == null; //true

 

不要试图通过转换数据类型来解释这个结论,因为:

 

Number(null); // 0

Number(undefined); // NaN

 

//在比较相等性之前,null 没有被转换为其他类型

null == 0 ; //false

 

但 === 会返回 false ,因为全等操作 === 在比较相等性的时候,不会主动转换分项的数据类型,而两者又不属于同一种类型:

 

undefined === null; //false,类型不相同

undefined !== null;  //true, 类型不相同

 

4、总结

 

用一句话总结两者的区别就是:undefined 表示一个变量自然的、最原始的状态值,而 null 则表示一个变量被人为的设置为空对象,而不是原始状态。所以,在实际使用过程中,为了保证变量所代表的语义,不要对一个变量显式的赋值 undefined,当需要释放一个对象时,直接赋值为 null 即可。

转载于:https://www.cnblogs.com/silence-Bear/p/7402528.html

<think>嗯,用户问的是前端面试题中undefinednull区别,怎么回答更全面。首先,我得回想一下自己学过的知识,确保理解正确。这两个概念在JavaScript中确实容易混淆,但又有明确的区别。 首先,应该从定义入手。undefined表示变量声明了但未赋值,而null是一个表示“无”的对象,是开发者主动赋予的值。比如,var a; 这里a就是undefined,而var b = null; 这里b被显式设置为null。 接着,类型不同。undefinedUndefined类型,而null是Object类型。这一点可能让初学者困惑,因为typeof null返回的是object,这其实是JavaScript的一个历史遗留问题。需要解释清楚,虽然null的类型是object,但它本身表示空值。 然后,比较转换。当使用==时,nullundefined是相等的,因为它们都表示“无”,但使用===时则不相等,因为类型不同。比如null == undefined返回true,而null === undefined返回false。此外,在数值转换时,null转为0,而undefined转为NaN,这可能影响数学运算的结果。 应用场景也需要说明。undefined通常由系统自动分配,比如函数参数未传入时,或者访问对象不存在的属性。而null常用于主动释放对象引用,或者作为函数的参数表示缺少对象。比如,开发者可能会将变量设为null来清除引用,帮助垃圾回收。 另外,可以提到默认行为。例如,函数没有return语句时,默认返回undefined。JSON处理时,null可以被序列化,而undefined会被忽略,这可能影响数据传递。 可能还需要补充一些常见的面试问题,比如如何判断一个变量是null还是undefined。使用typeof判断undefined,而判断null则需要全等运算符,因为typeof null返回的是object。例如,if (x === null)或者if (x === undefined)。 还要注意历史背景,比如为什么typeof null是object,这是因为JavaScript最初的实现中的错误,后来被保留下来,导致了这个不一致的结果。 最后,总结两者的区别,强调在开发中的正确使用,避免因为混淆而导致的bug。比如,主动使用null来初始化可能赋值为对象的变量,而undefined则让系统自动处理。 可能用户希望得到一个结构清晰、涵盖各个方面的回答,所以在组织答案时要分点说明,确保全面性。同时,举例子能帮助理解,比如变量声明后的默认值、函数返回值等实例。这样面试官会觉得候选人对JavaScript的理解比较深入,不仅知道区别,还能结合实际应用场景。</think>### 分步解释:`undefined``null`的区别及回答要点 --- #### **1. 核心定义区别** - **`undefined`** 表示变量已声明但未赋值时的默认值,或访问对象不存在的属性时的返回值。 ```javascript let a; // a 的值为 undefined let obj = {}; obj.key; // 访问不存在的属性,返回 undefined ``` - **`null`** 表示一个明确的“空值”,是开发者主动赋予的标识符,用于表示“无对象”或“空对象引用”。 ```javascript let b = null; // 显式赋值为 null,表示“无对象” ``` --- #### **2. 类型与`typeof`操作符** - **`undefined`** - 类型为 `Undefined` - `typeof` 返回 `"undefined"` ```javascript typeof undefined; // "undefined" ``` - **`null`** - 类型为 `Null`(ECMAScript 定义) - `typeof` 返回 `"object"`(历史遗留问题) ```javascript typeof null; // "object"(注意:这是语言设计缺陷) ``` --- #### **3. 相等性比较** - **宽松相等(`==`)** `null` `undefined` 在 `==` 比较中相等(设计上认为两者都表示“无”): ```javascript null == undefined; // true ``` - **严格相等(`===`)** 类型不同,结果为 `false`: ```javascript null === undefined; // false ``` --- #### **4. 数值转换行为** - **`Number()`转换** - `null` → **`0`** - `undefined` → **`NaN`** ```javascript Number(null); // 0 Number(undefined); // NaN ``` --- #### **5. 应用场景** - **`undefined`的常见场景** 1. 变量未赋值 2. 函数未传参数时的默认值 3. 对象属性未定义 ```javascript function test(param) { console.log(param); // 未传参 → undefined } ``` - **`null`的常见场景** 1. 显式清空对象引用(如释放内存) 2. 作为函数参数表示“无对象” 3. 初始化可能赋值为对象的变量 ```javascript let element = document.getElementById("non-existent-id"); // 未找到 → null ``` --- #### **6. 如何检测** - **检测`undefined`** ```javascript if (variable === undefined) { /* ... */ } // 严格比较 // 或使用 void 0(避免 undefined 被重写的风险) if (variable === void 0) { /* ... */ } ``` - **检测`null`** ```javascript if (variable === null) { /* ... */ } // 必须用严格比较 ``` --- #### **7. 总结回答(面试要点)** 1. **定义差异**:`undefined`是未赋值的默认值,`null`是显式空对象引用。 2. **类型不同**:`typeof undefined`为`"undefined"`,`typeof null`为`"object"`。 3. **相等性**:`null == undefined`为`true`,但严格比较为`false`。 4. **数值转换**:`null`转数值为`0`,`undefined`为`NaN`。 5. **应用场景**:系统自动生成用`undefined`,主动清空用`null`。 --- #### **附加分:历史背景** - **`typeof null`的陷阱**:JavaScript 早期设计将`null`的二进制标签与对象相同,导致此问题,沿用至今。 - **JSON处理**:`JSON.stringify()`会忽略`undefined`属性,但保留`null`。 通过以上结构化回答,可体现对 JavaScript 底层机制的理解,助你在面试中脱颖而出!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值