我们在访问对象深处属性(或方法)或者是对不确定对象属性(或方法)时, 以前我们是这样做的:
// part1 if (low版本)
if (obj) {
if (obj.a) {
obj.a()
}
}
// part1 进化版
obj && obj.a && obj.a()
// dom元素
var checkEle = document.querySelector('#ele')
var inner = checkEle ? checkEle.innerText : undefined
var _inner = checkEle && checkEle.innerText
// 处理服务端返回数据
fetch('xxx?xx=xx').then(responese => {
// 当然这个地方我们可以解构
const { error, data: { count } } = responese
error === 0 ? count ? this.count = count : undefined : this.$toast('xxxxx')
})
// react
render() {
const { artical } = this.props
return (
<>
<div>xxxxx</div>
<span>{ artical ? artical.length ? '您已阅读完成' : '' : '当前文章加载中' }</span>
</>
)
}
这里有人要问了,非要做这种判断嘛~我觉得答案是肯定的,因为你在访问有一定深度的对象中的方法或者属性的时候,很容易因为上一级是
undefined
而导致你后续逻辑无法按照正常的逻辑进行。比如下面的错误:
这个时候,就要把我今天要介绍的
optional Chaining
请出来啦~
正文
介绍(其实是我自己编的)
解决处理访问一定深度对象的属性或方法为空值的一个运算符
(笔者自己编的~我个人觉得是一个运算符,23333)
所处阶段
stage-2
不过babel7
已经提供了对应的插件可以使用这个新特性了,在下面我也会告诉大家具体的用法。
句法(大概可以成为句法, 其实大概就是简单的使用方法)
optional chaining
: ?.
(重要的事情所三遍: 是?.
, ?.
, ?.
。不是?
, ?
, ?
。)
通过改写上面的一些例子我们来感受一下:
// part1 if (low版本)
if (obj) {
if (obj.a) {
obj.a()
}
}
// 使用 optional chaining
obj?.a?.()
// dom元素
var checkEle = document.querySelector('#ele')
var inner = checkEle ? checkEle.innerText : undefined
var _inner = checkEle && checkEle.innerText
// 使用 optional chaining
var inner = checkEle?.innerText
// 处理服务端返回数据
fetch('xxx?xx=xx').then(responese => {
// 当然这个地方我们可以解构
const { error, data: { count } } = responese
error === 0 ? count ? this.count = count.length : undefined : this.$toast('xxxxx')
// 使用 optional chaining
error === 0 ? (this.count = count?.length) : this.$toast('xxxxx')
})
babel
编译结果
// 源代码
const optionChainObj = {
step1: {
step2: {
step3: 'step3'
},
step4() {
console.log(123)
}
}
}
// babel编译后
"use strict";
var r, o, u = {
step1: {
step2: {
step3: "step3"
},
step4: function() {
console.log(123)
}
}
};
null == u || null === (r = u.step1) || void 0 === r || null === (o = r.step4) || void 0 === o || o.call(r);
// 备注: void 0 的结果是undefined
我们看上述的编译代码,其实是插件内部帮我们扩展了我们原来需要写的一些代码,但是整体上会让我们的代码更加的简洁并且可读性更高一些~
适用场景
obj?.prop // optional static property access
obj?.[expr] // optional dynamic property access
func?.(...args) // optional function or method call
- 不确定属性访问(上面的栗子就是哦)
- 可衔接运算符或者表达式使用
// 源代码
var testOptions = [ 1, 2, 3 ]
var x = 0
var curr = testOptions?.[++x]
console.log(curr)
// babel 编译过后
var c = [1, 2, 3]
, f = 0
, a = null == c ? void 0 : c[++f];
console.log(a);
- 不确定函数或者方法
// 源码
var fuc = (name = '') => { console.log(name) }
fuc?.('ok')
// babel 编译过后
var s = function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "";
console.log(e)
};
null == s || s("ok")
现在想用怎么办?
- 首先安装
babel
# 注意我们需要使用babel7.0及以上版本
npm install --save-dev @babel/core @babel/cli
- 安装
babel-plugin-syntax-optional-chaining
插件
npm install --save-dev @babel/plugin-syntax-optional-chaining
- 配置
.babelrc
{
"plugins": ["@babel/plugin-syntax-optional-chaining"]
}
现在,你可以愉快的使用optional chaining
啦~~
tip
切勿花式秀技巧,导致自己代码可读性下降。
你也可以关注我的公众号