JavaScript中的Java-esque OOP和jQuery失败

我正在研究一个项目,我真的想编写面向对象的JavaScript代码。 我刚开始阅读Douglas Crockford的JavaScript:The Good Parts ,我很快就意识到在JavaScript中编写Java-esque OOP将是一项艰巨的任务。

到目前为止,我写了类似下面的内容……

// index.html $(document).ready(function() { $().SetUpElements(); }); // this is in a different js file $.fn.SetUpElements = function() { // do stuff here $().UpdateElement(); }; // this is in yet another different js file $.fn.UpdateElement = function() { // do stuff here var element = new Element(id, name); // continue doing work }; function Element(id, name) { var id = id; var name = name; // other stuff }; 

……我的想法是希望对象/函数尽可能地重构和解耦; 我想尽可能多地重用代码。 我在不同的.js文件中传播了很多代码,目的是将特定的相关代码分组在一起,就像你在Java中编写不同的类一样。

由于我一直在学习更多关于jQuery的知识,我意识到符号$.fn.foo = function() { ... }; 实际上是将这个foo函数添加到所有jQuery对象的原型中。 这是我应该做的事吗? 我不知何故误用了jQuery?

我很感激有关如何在JavaScript中改进我的OOP方法的建议,我希望看到有关讨论此主题的资源/教程/文章/等的参考资料。 即使选择了答案,也请随时提供反馈。 我正在寻找你的建议……这就是我发布的原因:)

**注意:我没有开发jQuery插件。 我正在开发一个Web应用程序并大量使用jQuery。

我想说你创建方法的第一种方式是滥用jQuery。 jQuery.fn.foo语法通常保留给作用于DOM元素但通过使用空jQuery对象将它们用作静态函数的函数。

如果要在jQuery命名空间下创建静态函数,可以执行以下操作:

 jQuery.foo = function(){}; 

然后通过以下方式调用

 jQuery.foo(); 

代替:

 jQuery.fn.foo = function(){}; 

这可以让你做到:

 jQuery('#someElementId').foo(); 

就OOP而言。 有许多不同的方法(模块模式,原型,工厂……)。 我通常接近它的方法是创建一个Class作为静态函数,然后使用关键字new调用它

 (function($){ var undefined; $.ClassName = function(options){ var self = this; var cfg = $.extend(true, {}, this.defaults, options); // ******************** // start:private // ******************** function _init(){ }; // ******************** // start:public // ******************** this.methodName = function(){ }; _init(); }; $.ClassName.prototype.defaults = {}; })(jQuery); 

在重用function方面,有一个阈值,之后解耦比任何事情都更有害。 确保您保持模块化和组织的正确平衡。

如果它不是一个jquery插件,我会写这样的东西:

  var app = { init: function(){ app.SetUpElements(); }, SetUpElements: function() { return 'something'; }, etc: function() { } }; $(document).ready(app.init); 

关于在Javascript中执行OO,您应该观看Douglas Crockford的高级Javascript课程

如果您正在开发插件,通常最好尽可能避免污染jQuery和Global命名空间/原型。

在jQuery的网站上查看这个文档 ,它提供了如何提供对各种可重用function的访问的出色解释,同时只在jQuery对象上声明了一个名称。

我看到的另一种方法是在jQuery命名空间上为你的插件提供单个init函数,然后在Global命名空间中提供一个额外的插件特定名称,它提供对函数/成员的更直接访问等。 Galleria插件是如何做到这一点的一个很好的例子。 检查他们的文档,以及他们设置插件结构的方式。

编辑

在看到你没有插件之后:我所说的很多东西仍然适用于一般的jQuery开发(实际上,一般来说也适用于开发)。

在您的特定情况下,由于您没有在进行函数调用时使用jQuery选择器,因此这些函数可能很容易附加到您自己制作的原型上,可以放在Global命名空间中。

就命名空间而言,请查看此问题的已接受答案,以获取如何正确执行此操作的示例: 如何在JavaScript中声明命名空间?

这里是JavaScript中OO的一个很好的资源。 在尝试围绕这个概念时,我使用了这篇文章: http : //mckoss.com/jscript/object.htm

您好像将所有代码都编写为jQuery插件? 我不会这样做。 创建自己的命名空间。

将所有内容放在不同文件中的目标是什么? 除非它们是用于特定页面的脚本,否则这将使管理事务变得更加困难。 这些都看起来像一般的库函数。 除非你认为你想要在一个页面上加载一些页面,而不是全部加载,否则将它们全部放在一个文件中。

面向对象编程并不意味着跨文件分段。 这只是组织,当你不需要某些页面上的所有内容时,你应该把东西分成不同的文件。

正如大多数人已经提到的,除非您明确创建公共插件,否则不要使用jQuery自定义函数。 而是使用简单的对象表示法创建自己的命名空间,或者像模块模式更健壮的东西。 如果你想变得疯狂,可以在API之上使用API​​,通过使用Dean Edward’s Base获得更经典的OO模式。 最终目标是从jQuery API中提取您的function和设计需求。 这样,如果您需要将某些东西移植到Mootools或Prototype,那么完成起来会更简单。