ES6如何优雅实现类似Ruby .try的无错对象属性访问?
在ES6+中实现类似Ruby
.try 的优雅方案 当然有啦!虽然你问的是ES6,但其实ES2020引入的可选链操作符?.已经成为现代JavaScript的标配,完全对应Ruby .try 的核心能力——安全访问对象的属性/方法,不存在就返回undefined(和Ruby的nil逻辑一致),彻底替代你那种繁琐的多层&&判断。
1. 首选方案:可选链操作符 ?.
这是官方给出的最优雅的解决方式,用法和Ruby的.try一样直观:
基础用法示例
访问单层属性:
const obj = { hello: 'world' }; obj?.hello; // 返回 'world' const emptyObj = null; emptyObj?.hello; // 返回 undefined,不会报错访问深层嵌套属性:
替代你写的if (object && object.key && object.key.subkey) { return object.key.subkey },直接一行搞定:object?.key?.subkey;只要
object、key任意一层是null或undefined,就会直接返回undefined,不会抛出经典的Cannot read properties of undefined错误。调用方法(对应Ruby中调用方法的场景):
const obj = { greet: () => 'Hello there!' }; obj?.greet(); // 返回 'Hello there!' const nullObj = null; nullObj?.greet(); // 返回 undefined,不会报错访问数组/对象索引(对应你例子里的
{hello: 'world'}.try(:[], :hello)):const obj = { hello: 'world' }; obj?.['hello']; // 返回 'world' const arr = [1, 2, 3]; arr?.[0]; // 返回 1 const nullArr = null; nullArr?.[0]; // 返回 undefined
2. 自定义try函数(兼容旧环境)
如果你的项目还需要兼容不支持可选链的旧浏览器或Node.js版本,可以自己封装一个类似Ruby .try 的函数:
// 基础版:支持单个属性/方法访问 function tryAccess(target, prop) { if (target == null) return undefined; // 处理方法调用的场景 if (typeof prop === 'function') { return prop.call(target); } // 处理属性或索引访问 return target[prop]; } // 使用示例 const obj = { hello: 'world' }; tryAccess(obj, 'hello'); // 'world' tryAccess(null, 'hello'); // undefined // 调用方法 const objWithMethod = { greet: () => 'Hi!' }; tryAccess(objWithMethod, () => objWithMethod.greet()); // 'Hi!' // 进阶版:支持链式访问深层属性 function tryChain(target, ...props) { let current = target; for (const prop of props) { if (current == null) return undefined; current = current[prop]; } return current; } // 访问深层属性 tryChain(obj, 'key', 'subkey'); // 等价于 obj?.key?.subkey
不过说实话,现在主流环境都已经支持可选链了,除非有特殊兼容需求,不然优先用官方的?.,既简洁又符合标准规范。
补充:搭配空值合并操作符 ?? 设默认值
如果希望在属性不存在时返回一个默认值(而不是undefined),可以配合ES2020的空值合并操作符??使用:
const value = object?.key?.subkey ?? '默认值'; // 只有当object?.key?.subkey是undefined或null时,才会返回'默认值'
内容的提问来源于stack exchange,提问作者Augustin Riedinger
相关产品推荐
相关产品推荐

