一文彻底搞懂javascript中的undefined

undefined in javascript

undefined是可以说是javascript中最特殊的一个类型,许多其他语言中都没有这个类型。它表示一个变量已经声明,但还没有被赋值。

js 复制代码
let a; // a的值是undefined

如果没有掌握好undefined,则可能会写出一些非常业余的代码,我们来看一个例子,这是在做code review时遇到的真实例子,你能看出下面的代码有什么问题吗?

js 复制代码
function getUserName(user) {
  if (user) {
    return user.name;
  } else {
    return undefined;
  }
}

在揭晓答案之前,我们先系统学习一下什么情况下JavaScript会产生undefined类型。

1. 显式undefined类型

jsx 复制代码
const a = undefined;
console.log(a); // undefined.

2. 未初始化的变量

jsx 复制代码
let a;
console.log(a); // undefined.

3. 访问对象中不存在的属性

jsx 复制代码
const person = {
  name: 'zdd',
  age: 41,
};

console.log(person.gender); // undefined.


const a = [1, 2, 3];
console.log(a[3]); // 数组只有三个元素,而a[3]表示第四个元素,所以它们的值是undefined

4. 函数没有返回值

函数没有返回值的时候,实际上返回的就是undefined

jsx 复制代码
function test() {
  console.log('hello, world!');
}

console.log(test()); // undefined.

5. 调用函数没有传递对应的参数

下面的代码中,函数add没有传入任何参数,所以ab的值都是undefined

jsx 复制代码
function add(a, b) {
  console.log(a); // 输出undefined.
  console.log(b); // 输出undefined.
  return a + b;
}

add(); // 没有传递参数

undefined != not defined

需要注意的是,undefinednot defined是两个不同的概念。undefined表示一个变量已经声明但还没有被赋值,而not defined表示一个变量没有被声明。

jsx 复制代码
let a;
console.log(a); // undefined.
console.log(b); // error, b is not defined

undefined vs void 0

既然已经有了undefined,为什么有很多JavaScript库中还使用void 0呢? 原因就是undefined是一个值,而不是关键字,能被用户串改,看下面的代码:

jsx 复制代码
const undefined = 1; // undefined被用户篡改!

const add = (a, b) => {
  // 这里判断参数是否传入,结果失效了,因为undefined值在前面被改成了1
  if (a === undefined || b === undefined) {
    console.error('请输入两个数');
  } else {
    return a + b;
  }
};

add(1, 2); // 这里会执行add函数中的if分支,是不是很崩溃?

使用void 0就不会有这个问题。

jsx 复制代码
const undefined = 1;

const add = (a, b) => {
  // 写成void 0就没有问题了,无论undefined被改成什么,都不影响。
  if (a === void 0 || b === void 0) {
    console.error('请输入两个数');
  } else {
    return a + b;
  }
};

console.log(add(1, 2));

那么为什么void 0返回undefined呢?这是因为void是一个操作符,它的作用是对其后面的表达式求值,然后返回undefined。在JavaScript中,void 0等价于undefined,其实你也可以写void 1, void 'hello'等,结果都是undefined

void expression的求值规则 - 先对expression求值,然后返回undefined

正则表达式中的undefined

在正则表达式中,可以使用test来测试某个字符串是否满足特定的规则。

javascript 复制代码
console.log(/^hello/.test('hello, world!')); //true

如果你没有传递参数给test,那么它会尝试匹配字符串undefined.

javascript 复制代码
console.log(/undefined/.test()); // true

This is equivalent to the following code, since undefined convert to string is 'undefined', so the result is true.

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

详情请看这里

undefined vs null

undefinednull经常被放到一起比较,那么他们之间有什么区别呢?

  • undefined表示一个变量已经声明但还没有被赋值,
  • null表示一个变量已经被赋值为一个空值。
  • null是JS中的关键字,但是undefined是一个全局属性。

undefined与其他类型之间的转换

这里面比较特殊的是和数字类型之间的转换,undefined转换为数字类型时会返回NaN,而null转换为数字时会返回0

javascript 复制代码
console.log(String(undefined)); // "undefined"
console.log(Number(undefined)); // NaN
console.log(Boolean(undefined)); // false

注意null转换为其他类型时与undefined的区别

javascript 复制代码
console.log(String(null)); // "null"
console.log(Number(null)); // 0
console.log(Boolean(null)); // false

回到文章开始的问题,根据上面第四点,函数没有返回值时,返回的就是undefined,所以上面的代码可以简化为如下形式,else分支完全没有必要。

js 复制代码
function getUserName(user) {
  if (user) {
    return user.name;
  }
}

References:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#undefined_type
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void

相关推荐
kiritomzzz18 分钟前
Vue 插槽(Slot)全解析:从 Vue2 到 Vue3 核心用法与案例
前端·javascript·vue.js
漂流瓶jz8 小时前
Webpack如何实现万物皆可import?loader的使用/配置/手写实践
前端·javascript·webpack
ZC跨境爬虫9 小时前
跟着 MDN 学CSS day_41:显式轨道、隐式网格与区域命名放置
前端·javascript·css·ui·交互
Moment10 小时前
长上下文会最终杀死 Rag 吗?
前端·javascript·后端
kyriewen12 小时前
大文件上传最全指南:分片、断点续传、秒传,一篇就够了
前端·javascript·面试
我叫黑大帅12 小时前
解决聊天页内部滚轮改为页面滚动问题
javascript·后端·面试
新酱爱学习13 小时前
手搓 10 个 Skill 后,我把重复劳动收敛成了一套零依赖 CLI 工具
前端·javascript·人工智能
罗超驿13 小时前
13.JavaScript 新手入门指南:语法、变量、流程控制全解析
开发语言·javascript
ct97814 小时前
Three.js 性能优化(测量-定位-优化)
javascript·性能优化·three
陈_杨14 小时前
鸿蒙开发-疾阅App阅读训练功能技术解析
前端·javascript