专栏-null 和 undefined 到底是什么?

专栏-null 和 undefined 到底是什么?

很多人第一次学 JavaScript,都会被这两个东西绕住:

javascript 复制代码
null
undefined

看起来都像"没有值",为什么要搞两个?

我以前一直对这种 none/null/undefined 一类的东西很不理解。

不是因为它多复杂。

而是因为一直没人直接告诉我:

这玩意本质上就是语言提前放好的一个全局标记,一个哨兵。

关键先别把它们想得太神秘。

它们本质上都只是标记值 ,也可以叫哨兵值

text 复制代码
正常值
-> 真正的数据

标记值
-> 用来说明这里现在没有正常数据

问题不在于"空不空",而在于:

这个"没有",到底是谁放进去的?


一、nullundefined 分别在标记什么?

null 是程序员主动放进去的标记。

比如:

javascript 复制代码
const user = null;

这不是"还没值"。

而是:

我明确告诉程序,这里现在就是没有正常对象。

所以 null 更像是:

text 复制代码
人主动写进去的"没有"

undefined 不一样。

它通常不是你主动放的,而是 JavaScript 运行过程中自动给出来的结果。

比如:

javascript 复制代码
let x;
console.log(x); // undefined
javascript 复制代码
const obj = {};
console.log(obj.age); // undefined
javascript 复制代码
function f() {}
console.log(f()); // undefined

这些情况的共同点都一样:

这个位置是合法的,但程序最后没有拿到正常值。

所以可以把它压成一句话:

text 复制代码
null
-> 人主动标记"这里没有值"

undefined
-> 语言自动标记"这里没产生出值"

顺手再补一个最容易混的边界:

undefined 不是"变量根本不存在"。

javascript 复制代码
let x;
console.log(x); // undefined

这里变量是存在的,只是没值。

但如果你直接访问一个没声明过的变量,通常还是会报 ReferenceError


二、为什么很多语言只有 null,没有 undefined

因为很多语言根本不让你去读这种"还没产生值"的位置。

它们的处理方式不是:

text 复制代码
没值
-> 给你一个特殊值

而是:

text 复制代码
没值
-> 直接报错

比如在不少语言里:

  • 局部变量没初始化就不能读
  • 变量没声明就不能用
  • 本来该返回结果却没结果,会直接当成错误处理

既然这些情况都已经被错误机制拦住了,那就没必要再额外设计一个 undefined

所以很多语言最后只保留一种"空标记":

text 复制代码
null / nil / None

它表示的不是"程序没算出来",而是:

程序允许这里合法地没有对象。

这就是核心区别:

text 复制代码
很多语言:
主动表示没有
-> null

本来该有值但没产生
-> 直接报错
text 复制代码
JavaScript:
主动表示没有
-> null

没产生出值
-> undefined

所以 undefined 不是比 null 多了一种"空"。

它只是说明:

JavaScript 选择把"没产生出值"这件事,也做成了一个可以继续传递、继续判断的值。


三、把它当成一种"错误码设计",就更容易想通了

如果到这里还是觉得绕,可以再换一个更实用的角度理解:

说白了,这就是一种错误码设计,只不过它不是放在异常系统里,而是直接放在值系统里。

很多系统都会干这件事。

正常情况返回正常结果。

特殊情况不立刻中断,而是返回一个提前约定好的标记,让你自己继续判断。

比如:

text 复制代码
查到了
-> 返回真实对象

没查到
-> 返回 null
text 复制代码
拿到了属性值
-> 返回真实值

这个位置没有值
-> 返回 undefined

从这个角度看,nullundefined 其实没有那么特殊。

它们只是语言提前给你准备好的两个状态码。

而且理论上完全可以继续细分。

比如一门语言如果愿意,甚至还可以再造几个专门的标记:

text 复制代码
参数没传
-> 一个标记

属性不存在
-> 一个标记

函数没返回结果
-> 一个标记

只是 JavaScript 没继续细分,而是把很多场景都压到了 undefined 里。

很多别的语言走的是另一条路:

它们连这个标记都不想给,直接把这些情况判成错误。

所以最后你看到的表面现象才会是:

text 复制代码
JavaScript
-> null + undefined

很多别的语言
-> 只有 null

但本质上不是 JavaScript 多了一种神秘的空值。

而是它多保留了一类"缺值状态",并把它做成了一个可以继续传递的值。

相关推荐
用户900463370401 小时前
5MB vs 4KB vs 无限大:浏览器存储谁更强?
前端
小小小小宇1 小时前
Harness Engineering 全解析与应用
前端
神奇小汤圆2 小时前
别再只会用ArrayList了!Java集合框架的性能天花板到底在哪?
后端
神奇小汤圆2 小时前
Dubbo 的 SPI 和 JDK 的 SPI 有什么区别?
后端
叫我少年2 小时前
C# 字符串基础
后端
牧艺2 小时前
cos-design v3.0:从 15 个 Demo 到 49 个组件的视觉特效库
前端·视觉设计
lichenyang4532 小时前
ASCF 架构升级总览:WebRuntimePage 为什么要变薄
前端
道友可好2 小时前
从今天开始:你的第一个 Harness Engineering 实践
前端·人工智能·后端
Linsk2 小时前
组件 = 模板 + 业务逻辑
java·前端·vue.js