关注我的文章字符串不是错误,我想提请大家注意一个类似的问题通常是JavaScript,但在节点中具有特殊相关性。JS公司环境。
这个问题归结为{}
作为密钥由不受信任的用户提供的数据结构输入,以及通常用于断言密钥是否存在。
考虑一个使用创建的简单博客的示例快递。我们决定将博客文章存储在内存中{}
,由博客帖子slug索引。例如,此博客帖子将是posts['-object-is-not-a-hash']
.
我们开始写路线/创建
,它接受一些POST字段,如“标题”和“slug”,并将其传递给岗位
构造函数。
- 无功功率,无功功率帖子= {};
- 应用程序.邮递('/创建', 功能 (请求,物件) {
- 如果 (请求.身体.标题&&请求.身体.段塞) {
- //避免重复
- 如果 (!帖子[请求.身体.段塞]) {
- 立柱[请求.身体.段塞] = 新的 岗位(请求.身体);
- 资源.发送(200);
- } 其他的 {
- 资源.发送(500);
- }
- }
- });
我们试图避免重复的第一步是检查对象中是否存在密钥。
通常情况下,这会很好,但让我们考虑一下用户可以选择任何JavaScript对象作为名称:
- __defineGetter___defineSetter__valueOf
- __lookupGetter__查找设置器__
- 构造函数具有OwnProperty
- isPrototypeOf属性IsEnumerable
- toLocaleString到String
例如,如果用户想命名他的博客帖子“构造函数”
我们的程序将无法正常运行。因此,我们更改代码以利用hasOwnProperty公司
,这将允许检查属性是否已由我们设置:
- 如果 (!帖子.hasOwnProperty公司(请求.身体.段塞)) {
- 立柱[请求.身体.段塞] = 新的 岗位(请求.身体);
- 资源.发送(200);
- }
大多数JavaScript程序员已经熟悉hasOwnProperty公司
,因为在浏览器世界中,它是编写库的标准方式,在以下环境中运行良好对象.原型
被修改了,所以这个添加应该不会让人感到惊讶。
hasOwnProperty陷阱
然而,我们的计划仍然容易受到潜在不当行为的影响。假设我们的用户决定调用他的博客“hasOwnProperty”
。第一次执行检查时,所有操作都将正常,因为检查将返回false:
- ∞ ~节点
- > 无功功率,无功功率一= {};
- >一.hasOwnProperty公司(“hasOwnProperty”)
- 假
因此,我们的代码将设置hasOwnProperty公司
对象中的值岗位
实例,它是一个对象。现在,我们可以模拟用户再次尝试时会发生什么:
- >一.hasOwnProperty公司= {}
- {}
- >一.hasOwnProperty公司(“hasOwnProperty”)
- 类型错误: 财产 “hasOwnProperty”属于对象 #<Object>不是函数
- 在[对象 上下文]:1:三
因此:
- 我们的代码会抛出一个(潜在的)未捕获的异常。
- 执行我们的
/创建
路由将被中止,并且不会向用户发送响应。 - 请求将一直挂起,直到两端超时。
这个问题的解决方案是避免依赖“hasOwnProperty”由我们处理的对象提供,并使用来自对象.原型
。如果我们在测试对象上执行它,真的
将在我们按预期设置后返回:
- > 对象.原型.hasOwnProperty公司.呼叫(一, “hasOwnProperty”)
- 真的
结论
这个实验的第一个结论是,从我们决定使用JavaScript对象作为通用哈希表我们不能再依赖它的任何继承财产,特别是hasOwnProperty公司
(我们通常必须使用)。事实上,这种疏忽影响了节点。JS核心查询字符串库过去。
如果您的代码严重依赖于数据结构对于存在这样的碰撞,您可能需要考虑有
周围的实用程序:
- 功能有(对象,钥匙) {
- 返回 对象.原型.hasOwnProperty公司.呼叫(对象,钥匙);
- }
并按如下方式使用:
作为补充说明,您通常也应该在浏览器环境中坚持使用此方法。宿主对象,例如窗口
在旧的Internet Explorer版本中没有 hasOwnProperty公司
,导致代码中潜在的不一致行为。
资料来源:http://www.devthought.com/2012/01/18/an-object-is-not-a-hash网站/