ES6/2015中的零安全财产访问(和条件分配)

ᆼᆺᆼ*_*ᆼᆺᆼ 137 javascript coffeescript ecmascript-6 babeljs

是否有一个null-safe属性访问(空传播/存在)操作者在ES6(ES2015/JavaScript.next /和谐)等?.中的CoffeeScript例如?或者是否计划用于ES7?

var aThing = getSomething()
...
aThing = possiblyNull?.thing
Run Code Online (Sandbox Code Playgroud)

这将大致如下:

if (possiblyNull != null) aThing = possiblyNull.thing
Run Code Online (Sandbox Code Playgroud)

理想情况下,解决方案不应该分配(甚至undefined)到aThing如果possiblyNull是null

bas*_*ays 84

目前处于第1阶段的功能:可选链接.

https://github.com/tc39/proposal-optional-chaining

如果你想今天使用它,有一个Babel插件可以完成它.

https://github.com/davidyaha/ecmascript-optionals-proposal

更新(2017-08-01):如果你想使用官方插件,你可以尝试使用新变换的Babel 7的alpha版本.你的旅费可能会改变

https://www.npmjs.com/package/babel-plugin-transform-optional-chaining

  • 截至 2020 年 5 月,看起来当前的浏览器和 Typescript 已经实现了这一点! (4认同)
  • 看起来您也可以使用左侧的运算符,如果将任何内容评估为未定义,则不会评估右手。babel 插件可能会有所不同,我自己还没有测试过。 (2认同)

toc*_*lle 60

它不如?好.运算符,但要实现类似的结果,您可以这样做:

user && user.address && user.address.postcode
Run Code Online (Sandbox Code Playgroud)

由于null和undefined都是假值(参见此引用),&&只有在先例不为null或未定义时才访问运算符后的属性.

或者,您可以编写如下函数:

function _try(func, fallbackValue) {
    try {
        var value = func();
        return (value === null || value === undefined) ? fallbackValue : value;
    } catch (e) {
        return fallbackValue;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

_try(() => user.address.postcode) // return postcode or undefined 
Run Code Online (Sandbox Code Playgroud)

或者,具有后备值:

_try(() => user.address.postcode, "none") // return postcode or a custom string
Run Code Online (Sandbox Code Playgroud)

  • 这是我在互联网上找到的最干净的解决方案。我在打字稿中使用它:`_get<T>(func: () => T, fallbackValue?: T) :T` (2认同)
  • 如果未定义user.address.postcode,则_try(()=> user.address.postcode,“”)将返回undefined而不是“”“。因此代码`_try(()=> user.address.postcode,“”).length`将引发异常。 (2认同)

Gir*_*afa 32

不.你可以在JavaScript中使用lodash #get或类似的东西.

  • 是否有建议将其添加到ES7? (4认同)
  • @PeterVarga:很多.讨论太多了.语法对于此功能来说并不容易 (3认同)

Gib*_*olt 31

2020 解决方案,?.以及??

您现在可以直接使用?.(Optional Chaining) 内联来安全地测试是否存在。所有现代浏览器都支持它。

?? (Nullish Coalescing) 可用于在未定义或为空的情况下设置默认值。

aThing = possiblyNull ?? aThing
aThing = a?.b?.c ?? possiblyNullFallback ?? aThing
Run Code Online (Sandbox Code Playgroud)

如果属性存在,则?.进行下一个检查,或返回有效值。任何故障都会立即短路并返回undefined。

const example = {a: ["first", {b:3}, false]}

example?.a  // ["first", {b:3}, false]
example?.b  // undefined

example?.a?.[0]     // "first"
example?.a?.[1]?.a  // undefined
example?.a?.[1]?.b  // 3

domElement?.parentElement?.children?.[3]?.nextElementSibling

null?.()                // undefined
validFunction?.()       // result
(() => {return 1})?.()  // 1
Run Code Online (Sandbox Code Playgroud)

为确保默认定义值,您可以使用??. 如果您需要第一个真值,您可以使用||.

example?.c ?? "c"  // "c"
example?.c || "c"  // "c"

example?.a?.[2] ?? 2  // false
example?.a?.[2] || 2  // 2
Run Code Online (Sandbox Code Playgroud)

如果不检查 case,则 left-side 属性必须存在。如果没有,它会抛出异常。

example?.First         // undefined
example?.First.Second  // Uncaught TypeError: Cannot read property 'Second' of undefined
Run Code Online (Sandbox Code Playgroud)

?.浏览器支持- 90%,2021 年 7 月

??浏览器支持- 90%

Mozilla 文档

——

逻辑空赋值,2020+ 解决方案

目前正在向浏览器??=、||=和 中添加新的运算符&&=。它们并不能完全满足您的要求,但可能会导致相同的结果,具体取决于您的代码目标。

注意:这些在公共浏览器版本中还不常见,但 Babel 应该可以很好地转换。将随着可用性的变化而更新。

??=检查左侧是否未定义或为空,如果已定义则短路。如果不是,则左侧被分配右侧值。||=and&&=是相似的,但基于||and&&运算符。

基本示例

let a          // undefined
let b = null
let c = false

a ??= true  // true
b ??= true  // true
c ??= true  // false
Run Code Online (Sandbox Code Playgroud)

对象/数组示例

let x = ["foo"]
let y = { foo: "fizz" }

x[0] ??= "bar"  // "foo"
x[1] ??= "bar"  // "bar"

y.foo ??= "buzz"  // "fizz"
y.bar ??= "buzz"  // "buzz"

x  // Array [ "foo", "bar" ]
y  // Object { foo: "fizz", bar: "buzz" }
Run Code Online (Sandbox Code Playgroud)

浏览器支持2021 年 7 月 - 89%

Mozilla 文档

  • 这个问题也是关于条件赋值的 (2认同)

yag*_*ger 14

香草替代安全的财产访问

(((a.b || {}).c || {}).d || {}).e
Run Code Online (Sandbox Code Playgroud)

最简洁的条件赋值可能就是这个

try { b = a.b.c.d.e } catch(e) {}
Run Code Online (Sandbox Code Playgroud)


Ber*_*rgi 6

不,ES6中没有空传播运算符.您将不得不使用其中一种已知模式.

但是,您可以使用解构:

({thing: aThing} = possiblyNull);
Run Code Online (Sandbox Code Playgroud)

有很多讨论(例如这个)在ES7中添加这样的运算符,但没有一个真正起飞.