开发的原因
前端处理 JSON 数据是最基本的一个需求,无论是啥框架,能够方便简洁地拿到数据,可以大幅度地方便开发
主要功能
处理一些 JSON 数据,拿不到值,取默认值,具体可以看 README.md
NPM 地址
www.npmjs.com/package/js-safe-json

看了一些留言,分几个点回复一下
1、这个库不成熟,会优先考虑 lodash 之类成熟的库
想说 test 脚本是摆设吗,test 里面也写了很多测试,能通过测试,达到预期结果了,这个还算不成熟吗
2、.d.ts
个人不喜欢ts,npm的发包也没规定一定要ts吧
3、lodash 可以 _.get(object, 'a.b.c', 'default');
如果我要拿一个string类型的值,刚好假设说 a.b.c 是个数字,
那么我拿到的东西,我的预期是拿到字符串的值,这部分它是没办法实现的,而我的库能办到,同理数组类型那些也是一样
let obj = {
a: {
b: {
c: 233
}
}
}

// 会是 233
let lodashResult = _.get(obj, 'a.b.c', '');
// 会是 ‘233’
let myLibResult = fetchString(obj, 'a', 'b', 'c');

4、为啥不设计跟 lodash 一样的传参
用 a.b.c 这样,这个是可以,但是我不喜欢这样做,容易写错,这个东西,并没有一个标准说怎样好,我的习惯是分开,会更加注意参数的值,避免没必要的错误
5、这部分是后端处理的,前端没必要,或者说这部分的业务需求是什么
接口并不能保证健全,这也是我弄这个库的初衷,程序需要健壮性,不能全部指望后端,尤其是现在 Vue 跟 React 基本也依赖于数据是渲染虚拟DOM,所以数据的健壮性还是有必要的
另外的补充
1、lodash 我也在用处理数据,正常来说,这边只是先拿到预期类型结果的数据,再用 lodash 进行数据处理, lodash 更像是操作数据进行加工,达到需要渲染页面的数据结构
2、纯抛砖引玉,有些老哥建议就不错,有些就感觉随便写,啊这,蚌埠住了,吧啦吧啦,没啥意义吧,深拷贝的实现方式有多种,我也清楚,觉得多余,也没求你用我的东西呀,键盘侠是不需要什么成本的,我也很暴躁,我也没碍着你什么呀

这种需求有点不理解

这也要发个库么...

我愣住……

有用 不过应该是后端做的事

github.com/paularmstrong/normalizr
这种功能? 20.5k stars

首先,我这边第一反应就是为什么不用 lodash 的_.get 。

其次,我觉得取值之前都要已经知道是什么类型,而且要执行对应类型的取值方法:fetchString 、fetchBoolean 等,那我为什么不_.get("a.b.c") || false 或者 _.get("a.b.c") || "",大不了在使用比较过程中再用"!!"或者"+" 转换一下类型。

最后就是,这年头没 typescript 就算了,但是不能没有 type.d.ts ;

最最重要的一点就是,直接全量引入了一个 underscore,这个是很难接受的。 虽然您这边打包出来才几 kb,那是因为是用的 esm,没办法直接在 js 上使用。

为什么不用||?
let number = json.number || 0;

JSON 正反序列化器最重要的意义是保证类型安全,然后在此基础上加一些工程特性,比如 JSON 字段与 Model 字段名称映射,规则校验等

但对于切图仔来讲有点尴尬的是,JS 如果要做类型安全,那么 API 设计的就比较丑陋,一般需要声明一个 Schema,然后人工维护字段关系,这样就比较繁琐,而且代码不是那么随意抽插;如果要学习类似 JSON.NET 的声明式注解,虽然 API 会好看很多,感觉有点像 AOP,但项目一定要上 TypeScript 并且打开 emitDecoratorMetadata,因为要用到反射,但某些时候项目已经不能支持,或者类似 Vite 这样 ESBuild 的工具链,如果为了这一个特性就大动干戈就比较难受.

我觉得切图仔对 JSON 正反序列化器也是有需求的,我自己仿造 JSON.NET 的 API 做了一个序列化器,然后在公司项目中大规模使用了,公开的版本在这里 github.com/vuevert/Vert-Serializer,不过是需要 TS + 装饰器 + emitDecoratorMetadata 环境的.

这个我在项目里一般和数据访问层结合,然后 API 大概可能长这样:

()
class User {
 ()
 name: string = ''

 ('user_age') // 数据源字段名称可以和 Model 不一样,比如接口里为 user_age.
 age: number = 0 // 如果接口返回的不是 number 则取 0 作为默认值.
}

function getUserData (id: string) {
 return HttpService.get({
 url: '/user',
 data: {
 id
 },
 type: User
 })
}

getUserData('1') // Promise<User>

这样就可以直接把 JSON 变为 Model.

另外我个人喜欢在项目中将各个功能集成在 Model 上以便查找,避免分散代码:

()
class User {
 ()
 (1, 20, '请填写用户名,长度在 1- 20')
 name: string = ''

 ('user_age')
 (0, 120, '请填写正确的年龄.')
 age: number = 0 // 如果接口返回的不是 number 则取 0 作为默认值.
}

然后直接在视图中使用:

const userValidator = getValidator(User)

<Textfield rules={userValidator.name} />
<Textfield rules={userValidator.age} />

这样视图中就不需要再额外写验证器逻辑了.

其实这些设计非常传统.

格式炸了 😢

这是我硬盘最佩服 前端圈 的一点,每次 npm install 似乎都是一次海量小文件压测

啊这。。。。

github.com/towry-archived/term-cursor

火钳刘明,宣传下我 N 年前下的一个 NPM 裤。。

把 underscore 干掉了

怎么连个 .d.ts 都没有?

lodash 的 get

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

function clone(obj) {
 return JSON.parse(JSON.stringify(obj));
}

蚌埠住了

看上去就是取个默认值?

如果是服务端接受客户端发过来的不可信 JSON,可以定义 ajv.js.org 这种工具直接校验后,再取值使用。

况且现在 JS 有空值运算符了,连 lodash 这种省了,例如 a.b?.c?[1]?.d ?? 'default'。

有标准里的 optional chaining 优先考虑用标准里的特性,不用 optional chaining 也会优先考虑 lodash 这种成熟的库

_.get(object, 'a.b.c', 'default');

卑微后端偷偷问一下,前端 我想用 typesctipt 描述一个结构,想要 找到的一个 Json 序列化的办法(json.parse 或者第三方库都行) 能让我在 定义的 interface {} 中 有个 Map,让 json 中 object 被反序列化成 Map 而不是默认的 js object.

估计这库应该用不到.......
如果是#8 那种,还有点意思,不过一般前端项目也用不到吧

话说后端提供的接口没文档吗?字段还会随意变吗?

反感一个文件 100 多行的 npm,不算啥解决方案,纯脆一个 helper 方法,自己都能在项目里撸出来,想复用直接发布到公司私有 npm 源就行
有些小库就很好,比如 cookie, qs (URLSearchParams 有些场景有问题)。大家需要的其实是这种类型的库

几个工具方法凑起来就是一个库,感觉是在教别人怎么发 npm 包 。