使用jQuery对象的OOP:更改jQuery数组的原型与创建自己的对象树

介绍

对于我的新工作,我必须编写一个经典的下拉菜单示例,该示例高度可访问(通过鼠标和键盘)并且与屏幕阅读器兼容(通过正确管理WAI-ARIA属性和状态)。 我的团队由“正常”的人和身体残疾的人组成,他们说他们在此之前无法找到完全可访问的下拉菜单,所以我们正在努力创建自己的给予客户。

好吧,我来自Ruby on Rails背景,直到现在才编写复杂的JavaScript代码,所以我试图将我的OOP知识从Ruby应用到JS世界。 因为我非常了解CoffeeScript,并且它在后台提供了相当多的魔力,这使得使用类和inheritance变得容易(虽然JS是一种对象驱动的语言而且没有类这样的东西),我坚持使用CoffeeScript而不是简单的JS。

我正在尝试设置一个类似于下拉菜单的正确对象树:

  • 有一个Item类。
  • 有一个inheritance自ItemParentItem类。
  • 有一个RootParentItem类,它inheritance自ParentItem

这样,所有根项都是RootParentItem类型,所有其他父项(拥有自己的子菜单的项)都是ParentItem类型,所有“真实”菜单项(指向网站中某个位置的链接)都是类型Item

通过设置这个适当的对象树,我认为根据项目的类型处理不同的键操作,鼠标操作等是非常简单和合理的。 这有助于防止长程序意大利面条代码,我在许多其他提供类似function的JS库上看到过。

这是我目前工作的一个例子: http : //codepen.io/jmuheim/pen/fAjcx

现在经过深思熟虑之后我问了一个问题:创建自己的对象树是否合理,同时在后台拥有大量的jQuery数组并将它们保存在我的对象变量中? 它有点奇怪,有一个漂亮的树结构,但总是使用相同结构的“阴影”,比如说:jQuery数组。

如上所述,我来自一个高度面向对象的Ruby世界。 我对JavaScript世界中的清晰编码实践/模式没有任何经验,因此:

  • 你认为我的尝试是否合理?
  • 是否有更清洁(公开更多接受)的方式? 也许直接在jQuery数组的原型上工作会更合理吗? 怎么可能这样做呢?
  • 关于我的JS编码风格的任何其他评论?

我认为你的inheritance模型是倒退的。 听起来你希望“Item”成为“叶子”子类,但你说“ParentIteminheritance自Item”。 项应该实际上从ParentIteminheritance,依此类推。

在OO设计方面,它实际上取决于如何使用“在后台”的数组。 每个类实例的这些唯一列表是? 它们是实际在所有类实例之间共享的静态列表,还是仅仅是一种类实例之间的共享? 如果它是前者,那么有一个内部成员变量来为每个实例存储这些数组是有意义的。 如果是后者,那么在经典的OO术语中,您实际上是在谈论静态成员变量。 这可以通过将静态成员作为普通属性(并且如此访问)附加到Constructor对象来实现,而不是在原型上或在构造函数中分配给“this”。 一个例子:

 function A(name) { this.name = name; } A.prototype.doStuff = function() { A.staticList.push(this.name); }; A.staticList = []; var x = new A('foo'); var y = new A('bar'); x.doStuff(); y.doStuff(); A.staticList; // contains ['foo', 'bar'] 

并且所有“真实”菜单项(指向网站中某个地方的链接)都是Item类型。

我会考虑为从Iteminheritance的它们使用RealItemLinkItem类。

创建自己的对象树是否合理,同时在后台拥有大量jQuery数组并将它们保存在对象的变量中?

是。 这就是大多数使用MVC模型的应用程序 – 视图组件控制DOM,并将对它(或jQuery包装器)的引用保持为类中的属性/变量。

是否有更清洁(公开更多接受)的方式? 也许直接在jQuery数组的原型上工作会更合理吗?

我认为那不会更清洁。

怎么可能这样做呢?

是的,你可以inheritancejQuery集合 ,但我不推荐它。

关于我的JS编码风格的任何其他评论?

如果您使用某些函数式编程实践,代码可能会更加干燥,但我认为它很好。