ES6 / 2015中的空安全属性访问(和条件赋值)

2020/11/08 13:02 · javascript ·  · 0评论

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

var aThing = getSomething()
...
aThing = possiblyNull?.thing

大致如下所示:

if (possiblyNull != null) aThing = possiblyNull.thing

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

更新(2020-01-31):似乎人们仍在寻找这个,这是当前故事:

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

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

原件

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

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

如果您想今天使用它,可以使用Babel插件来完成。

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

它不如?好。运算符,但是要达到类似的结果,您可以执行以下操作:

user && user.address && user.address.postcode

由于nullundefined都是伪造的值(请参阅此参考资料),&&只有在先例不是null或未定义的情况下,才可以访问运算符之后的属性

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

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

用法:

_try(() => user.address.postcode) // return postcode or undefined 

或者,使用后备值:

_try(() => user.address.postcode, "none") // return postcode or a custom string

否。您可以在JavaScript中使用lodash#get或类似的方法。

香草替代品,可安全进入物业

(((a.b || {}).c || {}).d || {}).e

最简洁的条件分配可能是这样

try { b = a.b.c.d.e } catch(e) {}

不,ES6中没有空传播算子。您将不得不采用一种已知模式

您也许可以使用解构:

({thing: aThing} = possiblyNull);

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

按照此处的列表进行操作,当前没有提议向Ecmascript添加安全遍历。因此,不仅没有很好的方法可以做到这一点,而且在可预见的将来也不会添加它。

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

现在,您可以直接使用?.(可选链接)内联安全地测试存在性。所有现代的浏览器都支持它。

?? (空合并)可用于设置默认值(如果未定义或为null)。

aThing = possiblyNull ?? aThing
aThing = a?.b?.c ?? possiblyNullFallback ?? aThing

如果存在属性,则?.进行下一个检查,或返回有效值。任何故障都会立即短路并返回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

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

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

example?.a?.[2] ?? 2  // false
example?.a?.[2] || 2  // 2

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

example?.First         // undefined
example?.First.Second  // Uncaught TypeError: Cannot read property 'Second' of undefined

?.浏览器支持-2020年10月占82%

??浏览器支持-82%

Mozilla文档

-

逻辑无效分配,2020 +解决方案

当前正在将新的运算符添加到浏览器中??=||=&&=它们不能完全满足您的要求,但根据您的代码目标,可能会导致相同的结果。

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

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

基本范例

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

a ??= true  // true
b ??= true  // true
c ??= true  // false

对象/数组示例

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" }

浏览器支持2020年10月-70%

Mozilla文档

// Typescript
static nullsafe<T, R>(instance: T, func: (T) => R): R {
    return func(instance)
}

// Javascript
function nullsafe(instance, func) {
    return func(instance);
};

// use like this
const instance = getSomething();
let thing = nullsafe(instance, t => t.thing0.thing1.thingx);

安全的深度获取方法似乎很自然地适合underscore.js,但是问题是避免进行字符串编程。修改@Felipe的答案以避免字符串编程(或至少将边沿大小写推回调用方):

function safeGet(obj, props) {
   return (props.length==1) ? obj[keys[0]] :safeGet(obj[props[0]], props.slice(1))
}

例:

var test = { 
  a: { 
    b: 'b property value',
    c: { }
  } 
}
safeGet(test, ['a', 'b']) 
safeGet(test, "a.b".split('.'))  

我知道这是一个JavaScript问题,但我认为Ruby以所有要求的方式处理此问题,因此我认为这是一个相关的参考点。

.&,,try和&&具有优势和潜在的陷阱。这些选项的摘要如下:http : //mitrev.net/ruby/2015/11/13/the-operator-in-ruby/

TLDR;Rubyists的结论是,dig既易于使用,又可以更有力地保证null将被赋值。

这是TypeScript中的一个简单实现:

export function dig(target: any, ...keys: Array<string>): any {
  let digged = target
  for (const key of keys) {
    if (typeof digged === 'undefined') {
      return undefined // can also return null or a default value
    }
    if (typeof key === 'function') {
      digged = key(digged)
    } else {
      digged = digged[key]
    }
  }
  return digged
}

这可用于任何深度的嵌套和句柄功能。

a = dig(b, 'c', 'd', 'e');
foo = () => ({});
bar = dig(a, foo, 'b', 'c')

try前面的答案所示,方法同样适合在JS中阅读。它还不需要循环,这是此实现方式的一个缺点。

我认为这个问题需要在2018年进行一些刷新。可以在不使用任何库的情况下很好地完成此操作,Object.defineProperty()并且可以按以下方式使用:

myVariable.safeGet('propA.propB.propC');

我认为这是安全的(和js道德的),因为MDN中记录了的方法writeableenumerable定义definePropertyObject

功能定义如下:

Object.defineProperty(Object.prototype, 'safeGet', { 
    enumerable: false,
    writable: false,
    value: function(p) {
        return p.split('.').reduce((acc, k) => {
            if (acc && k in acc) return acc[k];
            return undefined;
        }, this);
    }
});

我整理了一个jsBin和控制台输出进行演示。请注意,在jsBin版本中,我还为空值添加了一个自定义异常。这是可选的,因此我将其排除在上面的最小定义之外。

欢迎改进

本文地址:http://javascript.askforanswer.com/es6-2015zhongdekonganquanshuxingfangwenhetiaojianfuzhi.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!