对象不是哈希

  devthought.com网站      2012-01-19 10:16:10      43,742          

关注我的文章字符串不是错误,我想提请大家注意一个类似的问题通常是JavaScript,但在节点中具有特殊相关性。JS公司环境。

这个问题归结为{}作为密钥由不受信任的用户提供的数据结构输入,以及通常用于断言密钥是否存在。

考虑一个使用创建的简单博客的示例快递。我们决定将博客文章存储在内存中{},由博客帖子slug索引。例如,此博客帖子将是posts['-object-is-not-a-hash'].

我们开始写路线/创建,它接受一些POST字段,如“标题”和“slug”,并将其传递给岗位构造函数。

  1. 无功功率,无功功率帖子= {};

  2. 应用程序.邮递('/创建', 功能 (请求,物件) {
  3.  如果 (请求.身体.标题&&请求.身体.段塞) {
  4.    //避免重复
  5.    如果 (!帖子[请求.身体.段塞]) {
  6. 立柱[请求.身体.段塞] = 新的 岗位(请求.身体);
  7. 资源.发送(200);
  8.    } 其他的 {
  9. 资源.发送(500);
  10.    }
  11.  }
  12. });

我们试图避免重复的第一步是检查对象中是否存在密钥。

  1. 如果 (!帖子[请求.身体.段塞]) {

通常情况下,这会很好,但让我们考虑一下用户可以选择任何JavaScript对象作为名称:

  1. __defineGetter___defineSetter__valueOf
  2. __lookupGetter__查找设置器__
  3. 构造函数具有OwnProperty
  4. isPrototypeOf属性IsEnumerable
  5. toLocaleString到String

例如,如果用户想命名他的博客帖子“构造函数”我们的程序将无法正常运行。因此,我们更改代码以利用hasOwnProperty公司,这将允许检查属性是否已由我们设置:

  1. 如果 (!帖子.hasOwnProperty公司(请求.身体.段塞)) {
  2. 立柱[请求.身体.段塞] = 新的 岗位(请求.身体);
  3. 资源.发送(200);
  4. }

大多数JavaScript程序员已经熟悉hasOwnProperty公司,因为在浏览器世界中,它是编写库的标准方式,在以下环境中运行良好对象.原型被修改了,所以这个添加应该不会让人感到惊讶。

hasOwnProperty陷阱

然而,我们的计划仍然容易受到潜在不当行为的影响。假设我们的用户决定调用他的博客“hasOwnProperty”。第一次执行检查时,所有操作都将正常,因为检查将返回false:

  1. ∞ ~节点
  2. > 无功功率,无功功率= {};
  3. >.hasOwnProperty公司(“hasOwnProperty”)

因此,我们的代码将设置hasOwnProperty公司对象中的值岗位实例,它是一个对象。现在,我们可以模拟用户再次尝试时会发生什么:

  1. >.hasOwnProperty公司= {}
  2. {}
  3. >.hasOwnProperty公司(“hasOwnProperty”)
  4. 类型错误: 财产 “hasOwnProperty”属于对象 #<Object>不是函数
  5. [对象 上下文]:1:

因此:

  • 我们的代码会抛出一个(潜在的)未捕获的异常。
  • 执行我们的/创建路由将被中止,并且不会向用户发送响应。
  • 请求将一直挂起,直到两端超时。

这个问题的解决方案是避免依赖“hasOwnProperty”由我们处理的对象提供,并使用来自对象.原型。如果我们在测试对象上执行它,真的将在我们按预期设置后返回:

  1. > 对象.原型.hasOwnProperty公司.呼叫(, “hasOwnProperty”)
  2. 真的

结论

这个实验的第一个结论是,从我们决定使用JavaScript对象作为通用哈希表我们不能再依赖它的任何继承财产,特别是hasOwnProperty公司(我们通常必须使用)。事实上,这种疏忽影响了节点。JS核心查询字符串库过去。

如果您的代码严重依赖于数据结构对于存在这样的碰撞,您可能需要考虑周围的实用程序:

  1. 功能(对象,钥匙) {
  2.  返回 对象.原型.hasOwnProperty公司.呼叫(对象,钥匙);
  3. }

并按如下方式使用:

  1. 如果 ((帖子,请求.身体.段塞)) { }

作为补充说明,您通常也应该在浏览器环境中坚持使用此方法。宿主对象,例如窗口在旧的Internet Explorer版本中没有 hasOwnProperty公司,导致代码中潜在的不一致行为。

资料来源:http://www.devthought.com/2012/01/18/an-object-is-not-a-hash网站/

JAVASCRIPT公司 目标 搞砸 节点。JS公司 

       

相关


  评论


crawlergo@gmail.com匿名 [答复]@ 2020-08-12 05:05:37
C类
匿名[答复]@ 2020-10-04 09:33:20

这是一个愚蠢而复杂的例子。你为什么不定义一个具体的类型?允许用户输入在不进行任何验证的情况下指定地图中的键似乎是一种反模式。 

匿名[答复]@ 2023-07-21 18:51:28

这个问题归结为{}作为一种数据结构,其中密钥由不受信任的用户输入提供,以及通常用于断言密钥是否存在的机制。

 

??? 为什么你认为会有不可信的用户输入?

这不是已经解决了成为对象或不笑的问题了吗



有趣的故事

是的,我是开发人员

是的,我是一名开发人员。我不会修理你的打印机。