在ES6 (ES2015/JavaScript.next/Harmony)中是否有一个空安全的属性访问(空传播/存在)操作符?比如CoffeeScript ?还是计划在ES7中?
var aThing = getSomething()
...
aThing = possiblyNull?.thing
大致如下:
if (possiblyNull != null) aThing = possiblyNull.thing
理想情况下,解决方案不应该分配(甚至未定义)一个东西,如果posblynull是空的
我认为这个问题在2018年需要重新审视一下。这可以在不使用Object.defineProperty()的任何库的情况下很好地完成,并可以如下使用:
myVariable.safeGet('propA.propB.propC');
我认为这是安全的(而且合乎js-ethical),因为Object的defineProperty方法现在有可写和可枚举的定义,如MDN中所述
函数定义如下:
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版本中,我还为空值添加了一个自定义异常。这是可选的,所以我把它排除在上面的最小定义之外。
欢迎改进
更新(2022-01-13):似乎人们仍在发现这一点,以下是目前的情况:
可选链接现在在规范(ES2020)中,并且被所有现代浏览器支持,更多的在存档建议中:https://github.com/tc39/proposal-optional-chaining
babel-preset-env:如果你需要支持没有它的旧环境,这可能是你想要的https://babeljs.io/docs/en/babel-preset-env
Babel v7插件:https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining
更新(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
一个安全的deep get方法似乎很适合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('.'))