es6使用场景
es6非空判断
示例1
es5
if(value !== null && value !== undefined && value !== ''){
//...
}
es6改进后
if(value??'' !== ''){
//...
}
空值合并运算符
读取对象属性的时候,如果某个属性的值是null
或undefined
,有时候需要为它们指定默认值。常见做法是通过||
运算符指定默认值。
const headerText = response.settings.headerText || 'Hello, world!';
const animationDuration = response.settings.animationDuration || 300;
const showSplashScreen = response.settings.showSplashScreen || true;
上面的三行代码都通过||
运算符指定默认值,但是这样写是错的。开发者的原意是,只要属性的值为null
或undefined
,默认值就会生效,但是属性的值如果为空字符串或false
或0
,默认值也会生效。
??
: 空值合并运算符。空值合并运算符将会遍历列表,并返回第一个不是 null
或 undefined
的值。
举例
null ?? 'hi' // 'hi'
undefined ?? 'hey' // 'hey'
false ?? 'hola' // false
0 ?? 'bonjour' // 0
'first' ?? 'second' // first
这个运算符的一个目的,就是跟链判断运算符?.
配合使用,为null
或undefined
的值设置默认值。
const animationDuration = response.settings?.animationDuration ?? 300;
上面代码中,如果response.settings
是null
或undefined
,或者response.settings.animationDuration
是null
或undefined
,就会返回默认值300。也就是说,这一行代码包括了两级属性的判断。
这个运算符很适合判断函数参数是否赋值。
function Component(props) {
const enable = props.enabled ?? true;
// …
注意
??
本质上是逻辑运算,它与其他两个逻辑运算符&&
和||
有一个优先级问题,它们之间的优先级到底孰高孰低。优先级的不同,往往会导致逻辑运算的结果不同。
现在的规则是,如果多个逻辑运算符一起使用,必须用括号表明优先级,否则会报错。
// 报错
lhs && middle ?? rhs
lhs ?? middle && rhs
lhs || middle ?? rhs
lhs ?? middle || rhs
上面四个表达式都会报错,必须加入表明优先级的括号。
(lhs && middle) ?? rhs;
lhs && (middle ?? rhs);
(lhs ?? middle) && rhs;
lhs ?? (middle && rhs);
(lhs || middle) ?? rhs;
lhs || (middle ?? rhs);
(lhs ?? middle) || rhs;
lhs ?? (middle || rhs);
条件判断
es5
if(
type == 1 ||
type == 2 ||
type == 3 ||
type == 4 ||
){
//...
}
es6改进
ES6中数组实例方法includes
const condition = [1,2,3,4];
if( condition.includes(type) ){
//...
}
数组过滤
es5数组过滤一般用filter
来实现
const a = [1,2,3,4,5];
const result = a.filter(
item =>{
return item === 3
}
)
es6
const a = [1,2,3,4,5];
const result = a.find(
item =>{
return item === 3
}
)
find
性能更加优秀,find
方法中找到符合条件的项就不会继续遍历数组。
扁平化数组
一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中。
const deps = {
'采购部':[1,2,3],
'人事部':[5,8,12],
'行政部':[5,14,79],
'运输部':[3,64,105],
}
let member = [];
for (let item in deps){
const value = deps[item];
if(Array.isArray(value)){
member = [...member,...value]
}
}
member = [...new Set(member)]
改进后
const deps = {
'采购部':[1,2,3],
'人事部':[5,8,12],
'行政部':[5,14,79],
'运输部':[3,64,105],
}
let member = Object.values(deps).flat(Infinity);
获取对象的全部属性值Object.values
。涉及到数组的扁平化处理,用ES6提供的flat
方法,还好这次的数组的深度最多只到2维,还要是遇到4维、5维深度的数组,是不是得循环嵌套循环来扁平化?
取值
取值在程序中非常常见,比如从对象obj
中取值。
const obj = {
a:1,
b:2,
c:3,
d:4,
e:5,
}
const a = obj.a;
const b = obj.b;
const c = obj.c;
const d = obj.d;
const e = obj.e;
或者
const f = obj.a + obj.d;
const g = obj.c + obj.e;
改进
const {a,b,c,d,e} = obj;
const f = a + d;
const g = c + e;
如果想创建的变量名和对象的属性名不一致,可以这么写:
const {a:a1} = obj;
console.log(a1);// 1
补充
ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined
、null
。否则会报错,故要给被解构的对象一个默认值。
const {a,b,c,d,e} = obj || {};
对象取值
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined
上面代码的第一个例子,等号左边的两个变量的次序,与等号右边两个同名属性的次序不一致,但是对取值完全没有影响。第二个例子的变量没有对应的同名属性,导致取不到值,最后等于undefined
。
如果解构失败,变量的值等于undefined
。
let {foo} = {bar: 'baz'};
foo // undefined
上面代码中,等号右边的对象没有foo
属性,所以变量foo
取不到值,所以等于undefined
。
如果变量名与属性名不一致,必须写成下面这样。
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
这实际上说明,对象的解构赋值是下面形式的简写
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
foo // error: foo is not defined
上面代码中,foo
是匹配的模式,baz
才是变量。真正被赋值的是变量baz
,而不是模式foo
。
与数组一样,解构也可以用于嵌套结构的对象。
let obj = {
p: [
'Hello',
{ y: 'World' }
]
};
let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
注意,这时p
是模式,不是变量,因此不会被赋值。如果p
也要作为变量赋值,可以写成下面这样。
let obj = {
p: [
'Hello',
{ y: 'World' }
]
};
let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]
合并数据
es5
const a = [1,2,3];
const b = [1,5,6];
const c = a.concat(b);//[1,2,3,1,5,6]
const obj1 = {
a:1,
}
const obj1 = {
b:1,
}
const obj = Object.assgin({}, obj1, obj2);//{a:1,b:1}
改进,考虑去重
const a = [1,2,3];
const b = [1,5,6];
const c = [...new Set([...a,...b])];//[1,2,3,5,6]
const obj1 = {
a:1,
}
const obj2 = {
b:1,
}
const obj = {...obj1,...obj2};//{a:1,b:1}
最新文章
- DP专辑
- Swift: 在Swift中桥接OC文件(自己创建的类文件、第三方库文件)
- mysql mysqldump只导出表结构或只导出数据的实现方法
- Chrome 浏览器跨域和安全访问问题 使用 chrome的命令行标记:disable-web-security 参数联调线上数据
- QNX环境
- 使用objdump objcopy查看与修改符号表
- 又一道软通动力7K月薪面试题——银行业务调度系统
- android自定义控件 onMeasure() 测量尺寸
- 基于SOAP的xml网络交互心得
- cassandra 数据到Java对象的映射绑定
- Opencv在linux下安装
- python 中list的深拷贝和浅拷贝
- 各数据库连接maven配置
- 195. Spring Boot 2.0数据库迁移:Flyway
- leetcode739
- CloneZilla 恢复系统报错Waiting for device dev/disk/by-id/.....
- Windows 7 上面安装 dotnet core 之后 使用 应用报错的处理:api-ms-win-crt-runtime-l1-1-0.dll 丢失
- 干了2个月java开发最深的体会
- (数据挖掘-入门-3)基于用户的协同过滤之k近邻
- cetos7 systemd 详解