在创建对象时假设非字符串键将使用 toString() 转换为字符串有多安全?

Posted

技术标签:

【中文标题】在创建对象时假设非字符串键将使用 toString() 转换为字符串有多安全?【英文标题】:How safe is to assume, when creating an object, that non-string keys will be converted to strings using toString()? 【发布时间】:2018-03-27 16:58:06 【问题描述】:

作为我编写的库的一部分,我想让用户将函数作为对象的键传递:

https://github.com/welldone-software/redux-toolbelt/tree/master/packages/redux-toolbelt#makereducer

例如,在下面,increaseBy 是一个带有自定义 toString() 的函数,它返回一个字符串,decreaseBy.TYPE 是一个字符串。

const reducer = makeReducer(
  [increaseBy]: (state, payload) => state + payload,
  [decreaseBy.TYPE]: (state, payload) => state - payload,
,  defaultState: 100 )

其中increaseBy 是一个具有自定义toString() 的函数,可解析为字符串。

JS translates any key to string 使用 toString() 所以它可以工作,但我的问题是:

安全性如何?

【问题讨论】:

从技术上讲,它在 ES2015 环境中是安全的。但是,您现在依赖于隐式类型强制。每个查看您的代码的人都无法立即知道该对象具有哪些属性名称。并考虑没有自定义 toString 的函数:const id = x => x; o = [id]: "foo" 产生 x => x: "foo" 是的,我知道。如果您查看我们的库,则从流程中可以清楚地看到。我不只是分配一个带有自定义toString() 的随机函数作为对象的键:) 【参考方案1】:

根据 ES6 规范,在第四步的 "ComputedPropertyName" 部分 "12.2.6.8 Runtime Semantics: Evaluation" 下,我们有:

    返回到PropertyKey(propName)。

第四步"7.1.14 ToPropertyKey ( argument )"下的哪个:

    返回 ToString(key)。

所以[expression] 的结果将变为toString。另一方面,any string is a valid key 用于属性,尽管其中一些只能通过方括号访问。

【讨论】:

正是我想要的。谢谢。 但我不明白您通过括号访问的评论。和我问的有什么关系? @VitalikZaidman 这与你所问的无关。我只想指出,并非所有属性都可以通过点表示法访问,其中一些只能使用方括号访问。

以上是关于在创建对象时假设非字符串键将使用 toString() 转换为字符串有多安全?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用包含连字符的键将对象解构为变量? [复制]

复用类@1

js中的object对象toString和valueOf的区别

Object.prototype.toString()

php面向对象之__toString()

在 Analytics Query 中使用多个分区键将数据存储在多个 Azure 存储表中