使用 jQuery 编写 OO Javascript

Posted

技术标签:

【中文标题】使用 jQuery 编写 OO Javascript【英文标题】:Writing OO Javascript with jQuery 【发布时间】:2011-08-19 17:31:03 【问题描述】:

我来自 Prototype JS 背景,通过使用 Class.create() 来鼓励 OO javascript。现在我正在做一些 JQuery 工作,并且我正在尝试编写一些结构合理的 JQuery 代码,例如,我可以从两个不同的单击事件处理程序调用相同的对象函数。

这是原型中的代码:

document.observe("dom:loaded", function() 

    // create document
    APP.pageHelper = new APP.PageHelper();


);

// namespace our code
window.APP = ;

// my class
APP.PageHelper = Class.create(

  // automatically called
  initialize: function(name, sound) 
    this.myValue = "Foo";

    // attach event handlers, binding to 'this' object
    $("myButton").observe("click", this.displayMessage.bind(this))

  ,

  displayMessage: function() 
    console.log("My value: " + this.myValue); // 'this' is the object not the clicked button!
  

);

我想知道如何在 JQuery 中复制以下代码,其中无法将函数调用绑定到调用它的对象,并且“this”始终是单击的元素。

我听说过一种方法可以使用 Douglas Crockford 的“模块”模式 (http://www.yuiblog.com/blog/2007/06/12/module-pattern/),但如果有人可以,我会很高兴告诉我你将如何使用 JQuery 和那个模式来实现上面的代码。

提前致谢。

【问题讨论】:

好问题...我自己就是一个 mootools 人,你有 Class 对象和 bind 方法来完成这个模式。在 jQuery 中,bind 完全是另外一回事! jQuery: Writing jquery in an object oriented way 的可能重复项 jQuery 和 OO 无关。如果你真的想使用 Javascript OO,你不会使用 jQuery =) jQuery 不是一个“OO 构建类”框架;这是一个 DOM+事件+动画 shizzle 框架。如果你想添加事件,打乱几个 html 节点并展示跳舞的独角兽,不要这样做 OO 风格:要简单易读。 【参考方案1】:

我根据这篇好文章滚动了自己的对象:

http://www.klauskomenda.com/code/javascript-programming-patterns/

我只是选择对我正在从事的项目有意义的模式。所以就像一个简单的例子来做你要求的事情是:

$.myNamespace.myClass = function (options) 
    this.settings = $.extend( ... defaults ... , options);
    this.init();
;
$.myNamespace.myClass.prototype.settings = 
    someValue: 'default',
    someSelector: '#myButton'
;
$.myNamespace.myClass.prototype.init = function () 
    var self = this;
    $(self.settings.someSelector).click(function (event) 
        console.log(self.settings.someValue);
    );
;

您在下面回答说您知道原型,但语法有点烦人。我认为这只是习惯一种语法而不是另一种语法的问题。我确信 Prototype 库使用闭包和 .prototype 就像我在上面所做的一样,并且就像下面建议的其他一些答案一样。最后,只写你觉得舒服的语法。使用 Coffee Script 的建议也很酷 - 无论你的船如何 :)

【讨论】:

对不起,我觉得我读得太快了。我在上面写了一些快速的示例代码。 (我假设了我常用的 jQuery 命名空间技巧:***.com/questions/527089/…)【参考方案2】:

您可以绝对地将事件绑定到 dom 元素之外的其他东西。只需使用$.proxy

说明:

接受一个函数并返回一个始终具有特定上下文的新函数。 添加的版本:1.4

 /**
  * @param function - The function whose context will be changed.
  * @param context - The object to which the context (this) of the function should be set.
  */
jQuery.proxy( function, context )

此方法对于将事件处理程序附加到上下文指向不同对象的元素最有用。此外,jQuery 确保即使您绑定从 jQuery.proxy() 返回的函数,如果传递了原始函数,它仍然会取消绑定正确的函数。

【讨论】:

超级棒,这正是我所需要的。很高兴知道它的存在并避免 bind() 混淆。我写了一个简短的解释,以便其他人可以看到我移植到 JQuery 的问题中的原始示例:flydillonfly.wordpress.com/2011/05/06/… 感谢分享链接。我很高兴能够提供帮助。【参考方案3】:

我发现写OO code in CoffeeScript 比Class.create() 或更低级别的prototype 更令人愉快。查看function binding 部分。

【讨论】:

【参考方案4】:

您不需要Class.create() 来用 javascript 编写类。

APP.PageHelper = function(name, sound)  // this is the constructor
    this.myValue = "Foo";
    // attach event handlers, binding to 'this' object
    $('#myButton').click($.proxy(this.displayMessage, this)); // use $.proxy instead of `bind`

APP.PageHelper.prototype =  // define more prototype functions here
    displayMessage: function() 
        console.log("My value: " + this.myValue); // 'this' is the object not the clicked button!
    
;

现在对于更复杂的继承类,我使用 John Resig 的 simple class inheritance。

我还将类分成文件,用闭包包裹。这将是PageHelper.js

;!!window['APP'] && (function (NS, $) 
    NS.PageHelper = Class.extend( // see link above
        // functions
        init: function ()  // constructor

        ,
        displayMessage: function()  

        
    );
)(window['APP'], jQuery);

【讨论】:

我知道使用.prototype 编写类的常规方法。您不需要需要 Class.create(),但如果您使用 Prototype,它会很方便。【参考方案5】:

我认为最好的 jQuery 类实现来自 John Resig 的博客 (http://ejohn.org/blog/simple-javascript-inheritance/)。我强烈推荐它;它与 Prototype JS 非常相似。

我在它上面写了一个库来简化 jQuery (https://github.com/arturnt/brickjs) 中的 OO 设计。例如,为了执行您正在执行的操作,您可以执行以下操作。

Comp.APP = ;
Comp.APP.PageHelper = Comp.extend(
    init: function(e) 
        this._super(e);
        this.myValue = "foo";
    ,
    "#myButton click": function() 
        console.log(this.myValue); //prints
    
);

【讨论】:

【参考方案6】:

如果您正在为 JQuery 寻找某种类似的 OOP 结构,您可以尝试http://code.google.com/p/jquery-klass/

这是我用的。

【讨论】:

以上是关于使用 jQuery 编写 OO Javascript的主要内容,如果未能解决你的问题,请参考以下文章

javascrip jquery 学习随笔

jQuery插件开发:jQuery类方法

OO总结III

这个 php 代码是不是按照 OO 原则正确编写?

5月21日 JavaScrip应用t练习

OO总结