Javascript 替换Typescript中Angular2的Elvis运算符
我的意思是说,在typescript中是否有一个操作符与angular2的Javascript 替换Typescript中Angular2的Elvis运算符,javascript,angular,typescript,Javascript,Angular,Typescript,我的意思是说,在typescript中是否有一个操作符与angular2的Elvis操作符类似 让我从如下对象获取关键点: this.myForm.name.first_name 如果first\u name不存在,则会抛出错误未定义的first\u name 是的,我可以用像这样的typescript的三元运算符处理这个错误 this.myForm.name ? this.myForm.name.first_name : '' this.myForm?.name?.first_name
Elvis操作符类似
让我从如下对象获取关键点:
this.myForm.name.first_name
如果first\u name不存在,则会抛出错误未定义的first\u name
是的,我可以用像这样的typescript的三元运算符处理这个错误
this.myForm.name ? this.myForm.name.first_name : ''
this.myForm?.name?.first_name
但有时候钥匙太长了
那么在typescript中有没有像angular2的Elvis操作符这样的操作符,我可以这样使用
this.myForm.name ? this.myForm.name.first_name : ''
this.myForm?.name?.first_name
2019年12月更新:TypeScript 3.7,相当于其他语言中已知的安全导航操作符。ECMAScript提案已进入第4阶段,因此将成为ES2020规范的一部分。有关更多信息,请参阅
2017年7月更新:正如JGFMK在评论中指出的,有一个名为ECMAScript的提案。如果/当提案达到第4阶段时,将添加到语言规范中
TypeScript中既没有安全导航也没有elvis操作符,据我所知,也没有可比性
有关参考信息,请参阅中的功能请求
. 以下是(我认为这是一个合理的理由):
暂时关闭这个。由于实际上没有任何特定于TypeScript的东西需要在表达式级别执行此操作,因此这种大型操作符更改应该在ES规范委员会进行,而不是在这里
重新评估这一点的一般绊脚石将是进入下一阶段的具体ES提案,或者ES委员会的普遍共识,即这一功能不会在很长时间内出现(这样我们就可以定义自己的语义,并合理地确定它们会“赢”)
该表示法的替代方法是重复使用逻辑AND运算符、try/catch或类似于getSafe(()=>this.myForm.name.first\u name)
,如中所述,或者使用空对象
在编写引用可能存在或不存在的属性/子属性的HTML时,我不能没有Elvis
我们不会写
this.myForm?.name?.first_name
我猜负责ES的人可能大部分时间都花在编写JS上,而不是编写访问对象属性的前端HTML,因此他们对为什么有人需要安全导航感到困惑
他们认为“没有人需要它”,“它允许错误保持沉默,从而可能在以后咬你”和“你将如何解释x?(y)
?”
在我等待未来ES规范包括Elvis操作员时,我的解决方案如下:
(((this.myForm || {}).name || {}).first_name )
简言之,在值可以是未定义
的每个阶段,您都可以或使用{}
来定义它,这样未定义的值就变成了一个空对象。一旦你把整件事放进括号,你就可以安全地尝试提取它的一个属性,因为你试图从{}
中提取的任何属性都只是未定义的,而不是实际的错误
当您有多个层时,它确实有点难看,但在许多情况下,它比必须使用一系列&&
逐步降低对象的级别更难看
用于阵列访问,或使用空阵列访问
如果导航到一个数组,例如,如果表单有许多名称,并且您希望选择第一个名称,则方法类似:
((((this.myForm || {}).names || [])[0] || {}).first_name )
如果链中的某个值为0或“”,会发生什么情况?
假设您希望从this.myForm.names[0].first\u name
中读取一个值“John”
通常会触发错误的典型情况是没有对象this.myForm
。我上面描述的公式不会出现错误,而是可以工作,并被解释为{}.first_name
,它是未定义的
(但不是错误)
现在想象一个怀有敌意的人偷偷地将this.myForm设置为0或“”或{}。我们现在会看到错误吗?否,因为Javascript认为值0或“”是错误的,{}是真实的,但它本身是{},所以this.myForm |{}
的计算结果为{},链的其余部分像以前一样变成默认值,并且该方法仍然有效,返回undefined
,而不是错误
例子
console.log(“每个示例首先显示解决方法的结果,然后不显示。”)
log(“a.这应该可以正常工作。”)
a={myForm:{姓名:[{名字:“约翰”,姓氏:“史密斯”}};
console.log(a.myForm.names[0]。名字)
console.log(((a.myForm | |{}).names | |[])[0]| |{}).first_name)
log(“b.我们已经删除了first_name属性。这仍然有效。”)
b={myForm:{姓名:[{姓氏:“史密斯”}]};
console.log(b.myForm.names[0]。名字)
console.log(((b.myForm | |{}).names | |[])[0]| |{}).first_name)
log(“c.我们已经删除了整个“names”数组。这由变通方法修复,但如果在没有变通方法的情况下运行,则会出现错误。”)
c={myForm:{};
console.log(((c.myForm | |{}).names | |[])[0]| |{}).first_name)
console.log(c.myForm.names[0]。first_name)
下面是一个看起来更详细的解决方案:
const elvis = (...xs: (() => any|null)[]): any => {
if(xs.length == 0) return null;
const y = xs[0]();
return xs.length == 1 || y == null ? y : elvis(...xs.slice(1));
};
const bla= {
a : 'hello',
b : null,
c: undefined
}
console.log("a:", elvis(() => bla));
console.log("a:", elvis(() => bla, () => bla.a));
console.log("a:", elvis(() => bla, () => bla.a, () => bla.a.length));
console.log("b:", elvis(() => bla, () => bla.b, () => bla.b.length));
console.log("c:", elvis(() => bla, () => bla.c, () => bla.c.length));
输出:
> a: {a: "hello", b: null, c: undefined}
> a: hello
> a: 5
> b: null
> c: undefined
否决票为什么?这个问题无效吗?你指的是。是一个三元缩写,用于隐式计算第一个操作数(如果为true)。感谢您的回答,除了三元运算符之外,还有其他方法吗?@PardeepJain当某些属性未定义时,您可以指定空对象:this.myForm.name=this.myForm.name |{}
。然后您可以确保定义了name
。另一种方法是定义一个默认的数据结构,然后使用您的实际数据覆盖它。没有意识到这是一个角度的调整。。。假设它被烘焙到了Typescript中……Duck类型只是运行时脚本的一种形式