![640?wx_fmt=jpeg](https://img-blog.csdnimg.cn/img_convert/0efebd95b2f187cbe1f6a8c66634adb3.png)
let company;
company; // => undefined
let person = { name: 'John Smith' };
person.age; // => undefined
let array = null;
array; // => null
let movie = { name: 'Starship Troopers', musicBy: null };
movie.musicBy; // => null
'abc'.match(/[0-9]/); // => null
TypeError: 'undefined' is not a function
TypeError: Cannot read property '<prop-name>' of undefined
type errors
function undefined() {
// problem solved
}
undefined 是什么鬼
Boolean: true 或 false
Number: 1, 6.7, 0xFF
String: "Gorilla and banana"
Symbol: Symbol("name") (starting ES2015)
Null: null
Undefined: undefined.
未为变量赋值时默认值为undefined。
未初始化的变量number
一个不存在的对象属性movie.year
或者不存在数组元素movies[3]
Undefined type是其唯一值为undefined 值的类型。
创建未定义的常见场景
2.1未初始化变量
function bigFunction() {
// code...
myVariable; // => Throws 'ReferenceError: myVariable is not defined'
// code...
let myVariable = 'Initial value';
// code...
myVariable; // => 'Initial value'
}
bigFunction();
专注且易懂:更容易理解模块的功能
可维护且更容易重构:模块中的更改会影响更少的模块
可重用:专注于单个任务,使模块更易于重用
可测试:可以更轻松地测试专注于单个任务的模块
![640?wx_fmt=other](https://img-blog.csdnimg.cn/img_convert/623c0ef0cee4761b4abe40e94682068c.png)
function someFunc(array) {
var index, item, length = array.length;
// some code...
// some code...
for (index = 0; index < length; index++) {
item = array[index];
// some code...
}
return 'some result';
}
function someFunc(array) {
// some code...
// some code...
const length = array.length;
for (let index = 0; index < length; index++) {
const item = array[index];
// some
}
return 'some result';
}
变量未暴露undefined状态,因此没有访问undefined的风险
将变量尽可能地移动到它们的使用位置会增加代码的可读性
高内聚的代码块在必要时更容易重构并提取到单独的函数中
2.2 访问不存在的属性
访问不存在的对象属性时,JS 返回undefined。
let favoriteMovie = {
title: 'Blade Runner'
};
favoriteMovie.actors; // => undefined
let favoriteMovie = {
title: 'Blade Runner'
};
favoriteMovie.actors[0];
// TypeError: Cannot read property '0' of undefined
first:元素插入数组的开头
last:元素在数组末尾插入。
append([10], { first: 0, last: false }); // => [10]
obj.prop!== undefined:直接与undefined进行比较
typeof obj.prop!=='undefined':验证属性值类型
obj.hasOwnProperty('prop'):验证对象是否具有自己的属性
'prop' in obj:验证对象是否具有自己的属性或继承属性
const object = { };
const prop = 'prop' in object ? object.prop : 'default';
prop; // => 'default'
const object = { };
const { prop = 'default' } = object;
prop; // => 'default'
char:包装的字符,例如 '(单引号)或“(双引号),默认为”。
skipIfQuoted:如果字符串已被引用则跳过引用的布尔值,默认为true。
function quote(str, config) {
const { char = '"', skipIfQuoted = true } = config;
const length = str.length;
if (skipIfQuoted
&& str[0] === char
&& str[length - 1] === char) {
return str;
}
return char + str + char;
}
quote('Hello World', { char: '*' }); // => '*Hello World*'
quote('"Welcome"', { skipIfQuoted: true }); // => '"Welcome"'
function quote(str, { char = '"', skipIfQuoted = true } = {}) {
const length = str.length;
if (skipIfQuoted
&& str[0] === char
&& str[length - 1] === char) {
return str;
}
return char + str + char;
}
quote('Hello World', { char: '*' }); // => '*Hello World*'
quote('Sunny day'); // => '"Sunny day"'
={}在解构赋值的右侧,确保在完全没有指定第二个参数的情况下使用空对象。
定义包含默认属性值的defaults对象
调用Object.assign({},defaults,unsafeOptions)来构建新的对象options。新对象从unsafeOptions接收所有属性,但缺少的属性从defaults对象获取。
const unsafeOptions = {
fontSize: 18
};
const defaults = {
fontSize: 16,
color: 'black'
};
const options = Object.assign({}, defaults, unsafeOptions);
options.fontSize; // => 18
options.color; // => 'black'
const unsafeOptions = {
fontSize: 18
};
const defaults = {
fontSize: 16,
color: 'black'
};
const options = {
...defaults,
...unsafeOptions
};
options.fontSize; // => 18
options.color; // => 'black'
2.3函数参数
函数参数隐式默认为undefined。
function multiply(a, b) {
a; // => 5
b; // => 3
return a * b;
}
multiply(5, 3); // => 15
function multiply(a, b) {
a; // => 5
b; // => undefined
return a * b;
}
multiply(5); // => NaN
function multiply(a, b) {
if (b === undefined) {
b = 2;
}
a; // => 5
b; // => 2
return a * b;
}
multiply(5); // => 10
function multiply(a, b = 2) {
a; // => 5
b; // => 2
return a * b;
}
multiply(5); // => 10
multiply(5, undefined); // => 10
2.4 函数返回值
隐式地,没有return语句,JS 函数返回undefined。
function square(x) {
const res = x * x;
}
square(2); // => undefined
function square(x) {
const res = x * x;
return;
}
square(2); // => undefined
function square(x) {
const res = x * x;
return res;
}
square(2); // => 4
空语句
let,const,var,import,export声明
表达语句
debugger 语句
continue 语句,break 语句
throw 语句
return 语句
function getNum() {
let num = 1;
return num;
}
getNum(); // => 1
function getNum() {
// Notice that semicolons are missing
let num = 1
return num
}
getNum() // => 1
function getPrimeNumbers() {
return
[ 2, 3, 5, 7, 11, 13, 17 ]
}
getPrimeNumbers() // => undefined
function getPrimeNumbers() {
return;
[ 2, 3, 5, 7, 11, 13, 17 ];
}
getPrimeNumbers(); // => undefined
function getPrimeNumbers() {
return [
2, 3, 5, 7, 11, 13, 17
];
}
getPrimeNumbers(); // => [2, 3, 5, 7, 11, 13, 17]
2.5 void 操作符
void 1; // => undefined
void (false); // => undefined
void {name: 'John Smith'}; // => undefined
void Math.min(1, 3); // => undefined
未定义的数组
const colors = ['blue', 'white', 'red'];
colors[5]; // => undefined
colors[-1]; // => undefined
const sparse1 = new Array(3);
sparse1; // => [<empty slot>, <empty slot>, <empty slot>]
sparse1[0]; // => undefined
sparse1[1]; // => undefined
const sparse2 = ['white', ,'blue']
sparse2; // => ['white', <empty slot>, 'blue']
sparse2[1]; // => undefined
undefined和null之间的区别
const obj = { firstName: 'Dmitri' };
obj.lastName; // => undefined
let nothing = undefined;
let missingObject = null;
nothing === missingObject; // => false
总结
未初始化的变量
不存在的对象属性或方法
访问越界索引的数组元素
不返回任何结果的函数的调用结果
减少未初始化变量的使用
使变量生命周期变短并接近其使用的位置
尽可能为变量分配初始值
多敷衍 const 和 let
使用默认值来表示无关紧要的函数参数
验证属性是否存在或使用默认属性填充不安全对象
避免使用稀疏数组
![640?wx_fmt=jpeg](https://img-blog.csdnimg.cn/img_convert/a3f520fb2e7de9288bcb5350b67f5ea7.png)
![640?wx_fmt=jpeg](https://img-blog.csdnimg.cn/img_convert/f35d2faca0a3674d7cbb4054e5d7b597.png)