实用的javascript面向对象设计模式的示例

时间:2010-09-16 00:17:10

标签: javascript jquery design-patterns oop

您在应用程序的javascript中使用了哪些面向对象的设计模式,为什么?

即使没有附加正式的设计模式,也可以随意发布代码。

我已经写了很多javascript,但是我还没有将很多面向对象的模式应用到我正在做的事情上,而且我确信我错过了很多。

7 个答案:

答案 0 :(得分:53)

以下是三种流行的JavaScript模式。由于closures

,这些很容易实现

您可能还想查看:

以下是Diaz提出的2008年Google I / O演讲,他在书中讨论了一些话题:

答案 1 :(得分:25)

<强>继承

我使用基于notation for inheritanceExtJS 3,我发现它与在Java中模拟经典继承非常接近。它主要运行如下:

// Create an 'Animal' class by extending
// the 'Object' class with our magic method
var Animal = Object.extend(Object, {
    move : function() {alert('moving...');}
});

// Create a 'Dog' class that extends 'Animal'
var Dog = Object.extend(Animal, {
    bark : function() {alert('woof');}
});

// Instantiate Lassie
var lassie = new Dog();

// She can move and bark!
lassie.move();
lassie.bark();

<强>命名空间

我同意Eric Miraglia坚持使用命名空间,因此上面的代码应该在窗口对象之外的自己的上下文中运行,如果您希望代码作为执行中的许多并发框架/库之一运行,这是至关重要的。浏览器窗口。

这意味着窗口对象的唯一方法是通过您自己的命名空间/模块对象:

// Create a namespace / module for your project
window.MyModule = {};

// Commence scope to prevent littering 
// the window object with unwanted variables
(function() {

    var Animal = window.MyModule.Animal = Object.extend(Object, {
         move: function() {alert('moving...');}
    });

    // .. more code

})();

<强>接口

您还可以使用更多高级OOP构造(如接口)来增强应用程序设计。 My approach to these是为了增强Function.prototype以获得这些方面的符号:

var Dog = Object.extend(Animal, {
     bark: function() {
         alert('woof');
     }
     // more methods ..
}).implement(Mammal, Carnivore);

OO模式

对于Java意义上的“模式”,我只发现Singleton pattern(非常适合缓存)和Observer pattern用于事件驱动的功能,例如在a时分配一些操作用户点击按钮。

利用观察者模式的一个例子是:

// Instantiate object
var lassie = new Animal('Lassie');

// Register listener
lassie.on('eat', function(food) {
   this.food += food;
});

// Feed lassie by triggering listener
$('#feeding-button').click(function() {
    var food = prompt('How many food units should we give lassie?');
    lassie.trigger('eat', [food]);
    alert('Lassie has already eaten ' + lassie.food + ' units');
});

这只是我的OO JS包中的一些技巧,希望它们对你有用。

如果你想沿着这条道路走下去,那么我建议您阅读Douglas Crockfords Javascript: the Good Parts。这是一本很棒的书。

答案 2 :(得分:20)

我是模块模式的粉丝。这是一种实现可扩展,非依赖(大多数时候)框架的方法。

示例:

框架Q的定义如下:

var Q = {};

添加功能:

Q.test = function(){};

这两行代码一起用于形成模块。模块背后的想法是它们都扩展了一些基础框架,在这种情况下Q,但不相互依赖(如果设计正确),并且可以包含在任何顺序中。

在模块中,首先创建框架对象(如果它不存在)(这是 Singleton 模式的示例):

if (!Q)
    var Q = {};

Q.myFunction = function(){};

这样,您可以在单独的文件中包含多个模块(如上图所示),并以任何顺序包含它们。其中任何一个都将创建框架对象,然后对其进行扩展。没有手动需要检查框架是否存在。然后,检查自定义代码中是否存在模块/功能:

if (Q.myFunction)
    Q.myFunction();
else
    // Use a different approach/method

答案 3 :(得分:6)

单例模式通常对“封装”和组织内容很有帮助。您甚至可以更改辅助功能。

var myInstance = {
  method1: function () {
    // ...
  },
  method2: function () {
    // ...
  }
};

cleanest way to implement a singleton in javascript

答案 4 :(得分:4)

我非常喜欢jquery的method chaining pattern,允许你在一个对象上调用几个方法。它使得在一行代码中执行多个操作变得非常容易。

示例:

$('#nav').click(function() {
   $(this).css('color','#f00').fadeOut();
});

答案 5 :(得分:3)

我非常喜欢使用jQuery插件的Decorator pattern。而不是修改插件以满足您的需求,编写一个自定义插件,只是转发请求并添加其他参数和功能。

例如,如果您需要一直传递一组默认参数,并且您需要稍微不同的行为与业务逻辑相关联,请编写一个执行pre和{{1}的插件工作是必要的,以满足您的需要,并传递您的默认参数,如果没有指定这些特定的参数。

这样做的主要好处是您可以更新库,而不用担心移植库更改。你的代码可能会破坏,但至少有可能不会。

答案 6 :(得分:3)

javascript世界中有用的模式之一是链接模式,它首先受到LINQ的欢迎,也用于jQuery。

这种模式使我们能够以链接的方式调用类的不同方法。

此模式的主要结构为

var Calaculator = function (init) {
    var result = 0;
    this.add = function (x) { result += (init + x); return this; };
    this.sub = function (x) { result += (init - x); return this; };
    this.mul = function (x) { result += (init * x); return this; };
    this.div = function (x) { result += (init / x); return this; };

    this.equals = function (callback) {
        callback(result);
    }

    return this;
};


new Calaculator(0)
    .add(10)
    .mul(2)
    .sub(5)
    .div(3)
    .equals(function (result) {
        console.log(result);
    });

这种模式的关键思想是this关键词,这使得访问计算机功能的其他公共成员成为可能。