用jQuery编写OO Javascript

时间:2011-05-05 21:03:05

标签: javascript jquery oop design-patterns prototypejs

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

以下是Prototype中的代码:

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'始终是单击的元素。

我听说道格拉斯克罗克福德'模块'模式的方法(http://www.yuiblog.com/blog/2007/06/12/module-pattern/),但我很乐意,如果有人可以告诉我如何使用JQuery和该模式实现上面的代码。

提前致谢。

6 个答案:

答案 0 :(得分:4)

我根据这篇好文章推出自己的对象:

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就像我上面所做的那样,并且像下面的其他一些答案一样。最后,只需编写您觉得舒服的语法。使用咖啡脚本的建议也很酷 - 无论你的船是什么漂浮:)

答案 1 :(得分:3)

您绝对可以将事件绑定到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()返回的函数,如果传递原始函数,它仍将解除绑定正确的函数。

答案 2 :(得分:1)

您不需要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);

答案 3 :(得分:1)

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

这就是我使用的。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

我认为最好的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
    }
});