在ES6 (ES2015/JavaScript.next/Harmony)中是否有一个空安全的属性访问(空传播/存在)操作符?比如CoffeeScript ?还是计划在ES7中?

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

大致如下:

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

理想情况下,解决方案不应该分配(甚至未定义)一个东西,如果posblynull是空的


当前回答


// The code for the regex isn't great, 
// but it suffices for most use cases.

/**
 * Gets the value at `path` of `object`.
 * If the resolved value is `undefined`,
 * or the property does not exist (set param has: true),
 * the `defaultValue` is returned in its place.
 *
 * @param {Object} object The object to query.
 * @param {Array|string} path The path of the property to get.
 * @param {*} [def] The value returned for `undefined` resolved values.
 * @param {boolean} [has] Return property instead of default value if key exists.
 * @returns {*} Returns the resolved value.
 * @example
 *
 * var object = { 'a': [{ 'b': { 'c': 3 } }], b: {'c-[d.e]': 1}, c: { d: undefined, e: 0 } };
 *
 * dotGet(object, 'a[0].b.c');
 * // => 3
 * 
 * dotGet(object, ['a', '0', 'b', 'c']);
 * // => 3
 *
 * dotGet(object, ['b', 'c-[d.e]']);
 * // => 1
 *
 * dotGet(object, 'c.d', 'default value');
 * // => 'default value'
 *
 * dotGet(object, 'c.d', 'default value', true);
 * // => undefined
 *
 * dotGet(object, 'c.d.e', 'default value');
 * // => 'default value'
 *
 * dotGet(object, 'c.d.e', 'default value', true);
 * // => 'default value'
 *
 * dotGet(object, 'c.e') || 5; // non-true default value
 * // => 5 
 * 
 */
var dotGet = function (obj, path, def, has) {
    return (typeof path === 'string' ? path.split(/[\.\[\]\'\"]/) : path)
    .filter(function (p) { return 0 === p ? true : p; })
    .reduce(function (o, p) {
        return typeof o === 'object' ? ((
            has ? o.hasOwnProperty(p) : o[p] !== undefined
        ) ? o[p] : def) : def;
    }, obj);
}

其他回答

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

香草替代安全的财产访问

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

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

try { b = a.b.c.d.e } catch(e) {}
// 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);

不,在ES6中没有空传播运算符。你必须选择一个已知的模式。

不过,你可以使用析构:

({thing: aThing} = possiblyNull);

有很多关于在ES7中添加这样一个操作符的讨论(例如这个),但直到几年后可选的链接语法在ES2020中标准化,才真正开始流行起来。

它不像?那样好。运算符,但要实现类似的结果,你可以这样做:

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

因为null和undefined都是假值(参见参考),所以只有当前面的属性不是null或undefined时,才会访问&&运算符后面的属性。

或者,你可以这样写一个函数:

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