JavaScript语法糖
1.解构赋值
数组解构
let [firstName, surname] = "John Smith".split(' ');
alert(firstName); // John
alert(surname); // Smith
我们可以将Object.entries() 方法与解构语法一同使用,来遍历一个对象的“键—值”对:
let user = {
name: "John",
age: 30
};
// 使用循环遍历键—值对
for (let [key, value] of Object.entries(user)) {
alert(`${key}:${value}`); // name:John, then age:30
}
对象解构
let options = {
title: "Menu"
};
let {width: w = 100, height: h = 200, title} = options;
alert(title); // Menu
alert(w); // 100
alert(h); // 200
嵌套解构
如果一个对象或数组嵌套了其他的对象和数组,我们可以在等号左侧使用更复杂的模式(pattern)来提取更深层的数据。
在下面的代码中,options 的属性 size 是另一个对象,属性 items 是另一个数组。赋值语句中等号左侧的模式(pattern)具有相同的结构以从中提取值:
let options = {
size: {
width: 100,
height: 200
},
items: ["Cake", "Donut"],
extra: true
};
// 为了清晰起见,解构赋值语句被写成多行的形式
let {
size: { // 把 size 赋值到这里
width,
height
},
items: [item1, item2], // 把 items 赋值到这里
title = "Menu" // 在对象中不存在(使用默认值)
} = options;
alert(title); // Menu
alert(width); // 100
alert(height); // 200
alert(item1); // Cake
alert(item2); // Donut
智能函数参数
我们可以用一个对象来传递所有参数,而函数负责把这个对象解构成各个参数:
let options = {
title: "My menu",
items: ["Item1", "Item2"]
};
function showMenu({
title = "Untitled",
width: w = 100, // width goes to w
height: h = 200, // height goes to h
items: [item1, item2] // items first element goes to item1, second to item2
}) {
alert( `${title} ${w} ${h}` ); // My Menu 100 200
alert( item1 ); // Item1
alert( item2 ); // Item2
}
showMenu(options);
完整语法和解构赋值是一样的:
对于参数对象,属性 incomingProperty 对应的变量是 varName,默认值是 defaultValue。
function({
incomingProperty: varName = defaultValue
...
})
请注意,这种解构假定了 showMenu() 函数确实存在参数。如果我们想让所有的参数都使用默认值,那我们应该传递一个空对象:
showMenu({}); // 不错,所有值都取默认值
showMenu(); // 这样会导致错误
我们可以通过指定空对象 {} 为整个参数对象的默认值来解决这个问题:
function showMenu({ title = "Menu", width = 100, height = 200 } = {}) {
alert( `${title} ${width} ${height}` );
}
showMenu(); // Menu 100 200
在上面的代码中,整个参数对象的默认是 {},因此总会有内容可以用来解构。
总结
-
解构赋值可以简洁地将一个对象或数组拆开赋值到多个变量上。
-
解构对象的完整语法:
let {prop : varName = default, ...rest} = object这表示属性
prop会被赋值给变量varName,如果没有这个属性的话,就会使用默认值default。没有对应映射的对象属性会被复制到
rest对象。 -
解构数组的完整语法:
let [item1 = default, item2, ...rest] = array数组的第一个元素被赋值给
item1,第二个元素被赋值给item2,剩下的所有元素被复制到另一个数组rest。 -
从嵌套数组/对象中提取数据也是可以的,此时等号左侧必须和等号右侧有相同的结构。
2.JSON处理
JavaScript 提供了如下方法:
JSON.stringify将对象转换为 JSON。JSON.parse将 JSON 转换回对象。
JSON.stringify()
方法 JSON.stringify(student) 接收对象并将其转换为字符串。
得到的 json 字符串是一个被称为 JSON 编码(JSON-encoded) 或 序列化(serialized) 或 字符串化(stringified) 或 编组化(marshalled) 的对象。我们现在已经准备好通过有线发送它或将其放入普通数据存储。
请注意,JSON 编码的对象与对象字面量有几个重要的区别:
- 字符串使用双引号。JSON 中没有单引号或反引号。所以
'John'被转换为"John"。 - 对象属性名称也是双引号的。这是强制性的。所以
age:30被转换成"age":30。
let student = {
name: 'John',
age: 30,
isAdmin: false,
courses: ['html', 'css', 'js'],
spouse: null
};
let json = JSON.stringify(student);
alert(typeof json); // we've got a string!
alert(json);
/* JSON 编码的对象:
{
"name": "John",
"age": 30,
"isAdmin": false,
"courses": ["html", "css", "js"],
"spouse": null
}
*/
JSON 是语言无关的纯数据规范,因此一些特定于 JavaScript 的对象属性会被 JSON.stringify 跳过。
即:
- 函数属性(方法)。
- Symbol 类型的键和值。
- 存储
undefined的属性。
支持嵌套对象转换,并且可以自动对其进行转换。
let meetup = {
title: "Conference",
room: {
number: 23,
participants: ["john", "ann"]
}
};
alert( JSON.stringify(meetup) );
/* 整个结构都被字符串化了
{
"title":"Conference",
"room":{"number":23,"participants":["john","ann"]},
}
*/
但是不得有循环引用。
let room = {
number: 23
};
let meetup = {
title: "Conference",
participants: ["john", "ann"]
};
meetup.place = room; // meetup 引用了 room
room.occupiedBy = meetup; // room 引用了 meetup
JSON.stringify(meetup); // Error: Converting circular structure to JSON
手写JSON时的典型错误,此外,JSON 不支持注释。向 JSON 添加注释无效。
let json = `{
name: "John", // 错误:属性名没有双引号
"surname": 'Smith', // 错误:值使用的是单引号(必须使用双引号)
'isAdmin': false // 错误:键使用的是单引号(必须使用双引号)
"birthday": new Date(2000, 2, 3), // 错误:不允许使用 "new",只能是裸值
"friends": [0,1,2,3] // 这个没问题
}`;
JSON.parse()
例如:
// 字符串化数组
let numbers = "[0, 1, 2, 3]";
numbers = JSON.parse(numbers);
alert( numbers[1] ); // 1
对于嵌套对象:
let userData = '{ "name": "John", "age": 35, "isAdmin": false, "friends": [0,1,2,3] }';
let user = JSON.parse(userData);
alert( user.friends[1] ); // 1
总结
- JSON 是一种数据格式,具有自己的独立标准和大多数编程语言的库。
- JSON 支持 object,array,string,number,boolean 和
null。 - JavaScript 提供序列化(serialize)成 JSON 的方法 JSON.stringify 和解析(反序列化) JSON 的方法 JSON.parse。
- 这两种方法都支持用于智能读/写的转换函数。
- 如果一个对象具有
toJSON,那么它会被JSON.stringify调用。
3.运算符
可选链操作符?.与空值合并操作符??
在开发过程中,我们可能需要获取深层次属性,例如 system.user.addr.province.name。但在获取 name 这个属性前需要一步步的判断前面的属性是否存在
在编写代码时,如果某个属性不为 null 和 undefined,那么就获取该属性,如果该属性为 null 或 undefined,则取一个默认值
let a = null;
let b = undefined;
a?. // true
b?. // true
a ?? "default" // "default"
b ?? "default" // "default"
隐式转换符!!
!!将值转换为布尔值
!!0 // false
!!1 // true
!!"" // true
!![] // true
!!{} // true
!!null // false
!!undefined // false
!!NaN // false