在了解
undefined
数据类型之前,我们来复习一下js数据类型。
JS 的数据类型包括:
- Boolean:
和true
false
- Number: 整数
和浮点数1
1.2
- String:
Conan Wang
- Null:
null
- Undefined:
undefined
- Symbol:
(ES2015)Symbol("name")
undefined 的数据类型:
typeof undefined === “undefined”; //true
2. 导致undefined的常见场景
2.1 未初始化变量
尚未赋值的(未初始化)的声明变量默认为
undefined
var res;
console.log(typeof res); //undefined
技巧1 : 使用let 和 const 来代替的 var
const 和 let 具有块级作用域,在声明行之前存在于暂时性死区。
当变量一次性且永久地接收到一个值时,建议使用const声明const声明,它创建一个不可变的绑定。
技巧2 :增加内聚性
内聚描述模块的元素(命名空间、类、方法、代码块)内聚在一起的程度。凝聚力的测量通常被称为高凝聚力或低内聚力。
高内聚是优选的,因为它建议设计模块的元素以仅关注单个任务,它构成了一个模块。
- 专注且易懂
- 可维护且更容易重构
- 可重用
-
可测试
高内聚和低耦合是一个设计良好的系统的特征。
代码块本身可能被视为一个小模块,为了尽可能实现高内聚,需要使用变量尽可能接近使用它们代码块的位置。
2.2 访问不存在的属性
访问不存在的对象属性时,JS返回的 undefined
var obj = {
name: 'conan';
}
//使用属性选择器obj.age访问不存在的属性age将被计算为`undefined`;
本身访问不存在的属性不会引发错误,但是尝试从不存在的属性中获取数据时就会发生出问题。
技巧3 检查属性是否存在
JS提供了很多方法来确定对象具有特定属性:
-
: 直接与obj.name !== undefined
进行比较undefined
-
: 验证属性值类型typeof obj.name !== 'undefined'
- obj.hasOwnProperty(‘name’) : 验证对象是否具有自己的属性 仅在对象自己的属性中进行验证
-
: 验证对象的是否具有自己的属性或继承属性'name' in obj
建议使用操作符,它的语法短小精悍。
in
操作符的存在表明一个明确的意图,即检查对象是否具有特定的属性,而不访问实际的属性值。
in
技巧4 解构访问对象属性
技巧5 用默认属性填充对象
2.3 函数参数
函数参数隐式默认为 undefined
技巧6:使用默认参数值
2.4 函数返回值
隐式地, 没有语句, JS函数返回
return
.
undefined
技巧7:不要相信自动插入分号
JS中的以下语句必须以分号结尾:
- 空语句
-
,let
,const
,var
,import
声明export
- 表达语句
-
语句debugger
-
语句,continue
语句break
-
语句throw
-
语句return
void 操作符
void <expression>
计算表达式计算结果如何都返回
undefined
.
3. 未定义的数组
访问越界索引的数组元素时,会得到
undefined
.
var arr = [name, age, desc];
arr[5]; //=> undefined
访问稀疏数组的间隙(空槽)时,也会得到
undefined
.
4. undefined 和 null 之间的区别
两个特殊值都表示空状态,主要区别在于
undefined
表示尚未初始化的变量的值,
null
表示故意不存在对象。
var num;
console.log(num);//undefined
// num 变量未定义,这清楚的表明未初始化的变量。
undefined == null; //true
undefined === null; //false
总结
undefined
的存在是JS的允许性质的结果,它允许使用:
- 未初始化的变量
- 不存在的对象属性或方法
- 访问越界索引的数组元素
- 不返回任何结果的函数的调用结果
减少代码中的
undefined
关键字的出现:
- 减少未初始化变量的使用
- 使变量生命周期变短并接近其使用的位置
- 尽可能为变量分配初始值
- 多敷衍 const 和 let
- 使用默认值来表示无关紧要的函数参数
- 验证属性是否存在或使用默认属性填充不安全对象
- 避免使用稀疏数组