JavaScript 中的可选链

IT技术 javascript optional-chaining
2021-01-20 10:51:21

我最近一直在用 Swift 编程。今天,当问题突然出现在我面前时,我在 JavaScipt 中做了一些工作:

是否有类似于 JavaScript 中的可选链的东西?一种undefined is not an object没有任何变量的预防方法

例子:

function test(){
   if(new Date() % 2){
      return {value: function(){/*code*/}};
   }
} 

test().value();

会失败一半,因为有时会test返回 undefined。

我能想到的唯一解决方案是一个函数:

function oc(object, key){
   if(object){
      return object[key]();
   }
}

oc(test(), 'value');

我希望能够执行以下操作:

test()?.value()

问号后面的部分只有在test返回一个对象时才执行

但这不是很优雅。有什么更好的吗?运算符的神奇组合?

编辑我知道我可以重写test以返回一些东西。但我想知道是否有诸如可选链接之类的东西。我对上述示例的特定解决方案不感兴趣如果无法控制返回 undefined 的函数,我也可以使用它。

6个回答

这是目前的第 4 阶段提案,您可以在此处查看其进度:https :
//github.com/tc39/proposal-optional-chaining

你今天可以使用 babel 插件:https :
//www.npmjs.com/package/babel-plugin-transform-optional-chaining

2020 年 1 月 11 日更新: Babel 现在默认支持可选链 https://babeljs.io/blog/2020/01/11/7.8.0

可选链运算符拼写为?.它可能出现在三个位置:

obj?.prop       // optional static property access
obj?.[expr]     // optional dynamic property access
func?.(...args) // optional function or method call

笔记:

为了允许foo?.3:0被解析为foo ? .3 : 0(根据向后兼容性的要求),在词法语法级别添加了一个简单的前瞻,以便?.在这种情况下字符序列不会被解释为单个标记(?.标记不能紧跟一个十进制数字)。

也值得一看:

https://github.com/tc39/proposal-nullish-coalescing

https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-nullish-coalescing-operator

这应该是 2020 年的精选答案。
2021-04-06 10:51:21

在纯 JavaScript 中,您必须进行类型检查或构建代码,以便您知道对象将存在。

CoffeeScript 是一种编译为 JavaScript 的语言,?.如果您愿意考虑预处理语言,它提供了一个用于安全链接的存在运算符

还有另一个讨论在这里你为什么不能在JS重现此问题。

ESDiscuss 论坛上也有关于向 JavaScript 的未来版本添加存在运算符的讨论不过,它似乎并不遥远,当然离实际使用还差得很远。在这一点上更多的想法。

我已经接受了您的回答,因为它确实回答了我的问题,与下面的其他答案不同,并且因为它提供了一些有趣的信息。
2021-04-03 10:51:21

您可以使用

test() && test().value();

或者

var testResult = test();
testResult && testResult.value();

如果你问我这与 Swift 的可选链最相似。

test() && test().value()如果test有副作用或者test返回除nullor之外的虚假值,是不合适的undefined,当然如果test()没有value属性,或者它的value属性不是函数它仍然会失败
2021-04-07 10:51:21

可选链已经登陆 JS。我们可以通过?.对象属性访问中运算符使用可选链它允许我们尝试访问可能不存在(即 are undefined的对象的属性而不会抛出错误。

这是一个代码示例:

const obj = {
  foo: {
    bar: 1
  }
};

// If we try to access property which doesn't exists
// it just returns undefined
console.log(obj.baz);

try {
  // Now we try to access a property of undefined which throws an error
  obj.baz.foz;
} catch (e) {
  console.dir(e.message);
}

// Now we use the optional chaining operator ?.
// We get undefined instead of an error
console.log(obj.baz?.foz);
            
console.log(obj.foo?.bar);

var Obj = {Prop: {name: 'peter'}}

console.log(Obj.Prop.name) console.log(Obj?.Prop?.name)

在第一句话中,您只是访问对象属性。问题是如果你发现Prop它不是一个对象,它会抛出一个异常。这就是可选的 chainig 运算符的原因

让我们说你尝试做Obj.Prop2.name你会得到,Uncaught TypeError: Cannot read property 'name' of undefined 如果你做了Obj.Prop2?.name,你只会收到undefined一个值,而不是一个异常。

这在访问深度嵌套的属性时特别有用。

警告:这是一个相对较新的 JS 功能,尚未在所有浏览器中实现,因此在将其用于生产应用程序时要小心。