undefined in javascript
undefined
是可以说是javascript中最特殊的一个类型,许多其他语言中都没有这个类型。它表示一个变量已经声明,但还没有被赋值。
1 | let a; // a的值是undefined |
如果没有掌握好undefined
,则可能会写出一些非常业余的代码,我们来看一个例子,这是在做code review时遇到的真实例子,你能看出下面的代码有什么问题吗?
1 | function getUserName(user) { |
在揭晓答案之前,我们先系统学习一下什么情况下JavaScript会产生undefined
类型。
1. 显式undefined
类型
1 | const a = undefined; |
2. 未初始化的变量
1 | let a; |
3. 访问对象中不存在的属性
1 | const person = { |
4. 函数没有返回值
函数没有返回值的时候,实际上返回的就是undefined
。
1 | function test() { |
5. 调用函数没有传递对应的参数
下面的代码中,函数add
没有传入任何参数,所以a
和b
的值都是undefined
。
1 | function add(a, b) { |
undefined
!= not defined
需要注意的是,undefined
和not defined
是两个不同的概念。undefined
表示一个变量已经声明但还没有被赋值,而not defined
表示一个变量没有被声明。
1 | let a; |
undefined
vs void 0
既然已经有了undefined
,为什么有很多JavaScript库中还使用void 0
呢? 原因就是undefined
是一个值,而不是关键字,能被用户串改,看下面的代码:
1 | const undefined = 1; // undefined被用户篡改! |
使用void 0
就不会有这个问题。
1 | const undefined = 1; |
那么为什么void 0
返回undefined
呢?这是因为void
是一个操作符,它的作用是对其后面的表达式求值,然后返回undefined
。在JavaScript中,void 0
等价于undefined
,其实你也可以写void 1
, void 'hello'
等,结果都是undefined
。
void expression
的求值规则 - 先对expression
求值,然后返回undefined
正则表达式中的undefined
在正则表达式中,可以使用test
来测试某个字符串是否满足特定的规则。
1 | console.log(/^hello/.test('hello, world!')); //true |
如果你没有传递参数给test
,那么它会尝试匹配字符串undefined
.
1 | console.log(/undefined/.test()); // true |
This is equivalent to the following code, since undefined
convert to string is 'undefined'
, so the result is true.
1 | console.log(/undefined/.test(undefined)); |
详情请看这里
undefined
vs null
undefined
和null
经常被放到一起比较,那么他们之间有什么区别呢?
undefined
表示一个变量已经声明但还没有被赋值,null
表示一个变量已经被赋值为一个空值。null
是JS中的关键字,但是undefined
是一个全局属性。
undefined与其他类型之间的转换
这里面比较特殊的是和数字类型之间的转换,undefined
转换为数字类型时会返回NaN
,而null
转换为数字时会返回0
。
1 | console.log(String(undefined)); // "undefined" |
注意null
转换为其他类型时与undefined
的区别
1 | console.log(String(null)); // "null" |
回到文章开始的问题,根据上面第四点,函数没有返回值时,返回的就是undefined
,所以上面的代码可以简化为如下形式,else分支完全没有必要。
1 | function getUserName(user) { |
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