资讯专栏INFORMATION COLUMN

深层属性,轻松提取

sydMobile / 2410人阅读

摘要:于是一些工具函数诞生了,比如的虽然它保证了开发者在提取属性的过程中不会因为遇到或之类的值而抛出,但缺点也很明显属性的路径被写成了字符串,开发者无法获得编辑器的自动补全与智能纠错。

面临的问题

假设有这样一个对象,表示的是 用户是否启用了回复通知的设置

const settings = {
    notification: {
        reply: {
            active: {
                true
            }
        }
        // ...其他设置项
    }
    // ...其他设置项
}

当开发者想要提取 active 的值,最直接的方法是这么做

const isNotificationReplyActive = settings.notification.reply.active

但这是不安全的,因为 JavaScript 中通常使用 nullundefined 分别表示未定义或未声明的值

typeof someVar === "undefined" // 未声明
let someVar = null // 已声明,未定义

实际开发过程中可能因为比如节省资源的考虑,当用户未进行过设置时,它的 notification 或者更深的某一级的值是 nullundefined,而非对象。

// 比如当未设置回复通知时,它是这样的
const settings = {
    notification: {
        // 没有 reply
    }
}

// 这种情况下, settings.notification.reply 的值是 undefined
// JS 中试图获取 undefined 上的 key 时会触发 TypeError
const isNotificationReplyActive = settings.notification.reply.active // TypeError!

于是开发者采取了这样的措施

const isNotificationReplyActive = settings
    && settings.notification
    && settings.notification.reply
    && settings.notification.reply.active
// 或者
try {
    const isNotificationReplyActive = settings.notification.reply.active
} catch (err) {
    // 错误处理
}

经验丰富的开发者都知道,这样做的缺点很多,在此就不展开了。

于是一些工具函数诞生了,比如 lodash 的 _.get

import _ from "lodash"
const isNotificationReplyActive = _.get(settings, "notification.reply.active")

虽然它保证了开发者在提取属性的过程中不会因为遇到 undefinednull 之类的值而抛出 TypeError ,但缺点也很明显——

属性的路径被写成了字符串,开发者无法获得 IDE/编辑器 的自动补全与智能纠错。

不能使用便捷的解构语法—— const { notification: { reply: { active } } } = settings

简直是一夜回到解放前。

解决方法 —— safe-touch

现在让我们来回顾一下本文开头的那张图——它即是本文的主角、上述所有问题的解决方案。

// 引入
import safeTouch from "safe-touch"

const settings = { /* ... */ }
// 包裹要提取的对象
const touched = safeTouch(settings)

// 把它当作函数调用,可以获得原始值
touched() === settings // true

// 亦可以直接获取 settings 上存在的属性,同样通过调用取得属性值
// 在现代化的 IDE/编辑器 中,这一过程可以给出智能提示与自动补全
touched.notification.reply.active() // 若依本文开头给出的例子,值为 true

// 可以安全地获取并不存在的属性,返回 undefined ,不会抛出 TypeError
touched.something.does.not.exist[Math.random()]() // undefined

// 支持解构
const { notification: { reply: { active, notExistingKey } } } = touched
active() // true
notExistingKey() // undefined
怎么做到的

其实不难,核心功能通过 ES6 的 Proxy 就可以实现。再结合 TypeScript 的类型判断(初学 TS,看了好久文档),生成 index.d.ts 供智能化的 IDE/编辑器 使用,就有了自动补全与智能提示。

短小的源码 repo (欢迎 Star / issue)

可以从 npm 获取

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96112.html

相关文章

  • [译] 最深刻而易懂的ES6解构教程

    摘要:被解构的数据项位于赋值运算符的右侧,可以是任何数组和对象的组合,允许随意嵌套。数组模式位于赋值运算符的左侧,被结构的数组在其右侧。 解构是ES6的新特性,用于从JavaScript对象和数组中提取数据,语法上比ES5所提供的更加简洁、紧凑、清晰。它不仅能减少你的代码量,还能从根本上改变你的编码方式。用的越多,你就会发现越多塑造数据和函数的方式,这些实现方式在过去几乎是不可能的。本文将深...

    AlphaGooo 评论0 收藏0
  • 前端进阶资源整理

    摘要:前端进阶进阶构建项目一配置最佳实践状态管理之痛点分析与改良开发中所谓状态浅析从时间旅行的乌托邦,看状态管理的设计误区使用更好地处理数据爱彼迎房源详情页中的性能优化从零开始,在中构建时间旅行式调试用轻松管理复杂状态如何把业务逻辑这个故事讲好和 前端进阶 webpack webpack进阶构建项目(一) Webpack 4 配置最佳实践 react Redux状态管理之痛点、分析与...

    BlackMass 评论0 收藏0
  • ES6:解构——JavaScript 从数组和对象中提取数据的优雅方法

    摘要:跳过数组中的元素学会了如何按顺序从数组中提取数据。解构方法中提供了很好的解决方案。从对象中提取数据依然从最基本的开始,提取从中提取和。 本文编译:胡子大哈 翻译原文:http://huziketang.com/blog/posts/detail?postId=58f41a06a58c240ae35bb8e6 英文连接:ES6: Destructuring — an elegant...

    GraphQuery 评论0 收藏0
  • 利用Mesosphere DC/OS在任意基础设施之上实现TensorFlow分布

    摘要:与其它可用于的软件包一样,新的软件包亦可利用来加速各类机器学习与深度学习应用。数据科学家们必须首先构建起机器学习模型,确保其适合分布式计算特性,而后将其映射至深层神经网络当中,最终编写代码以为这套新模型提供支持。 今天,我们兴奋地宣布在Mesosphere DC/OS服务目录当中发布TensorFlow的be...

    hightopo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<