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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3722820/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:52:10  来源:igfitidea点击:

Examples of practical javascript object oriented design patterns

javascriptjquerydesign-patternsoop

提问by ming yeow

What object oriented design patterns do you use in your application's javascript, and why?

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

Feel free to post code, even if there is no formal design pattern attached to it.

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

I have written plenty of javascript, but I have not applied much object orientated patterns to what I am doing, and I am sure i am missing a lot.

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

采纳答案by Daniel Vassallo

The following are three popular JavaScript patterns. These happen to be easily implementable because of closures:

以下是三种流行的 JavaScript 模式。由于闭包,这些碰巧很容易实现:

You may also want to check out:

您可能还想查看:

The following is a Google I/O talk from 2008 presented by Diaz, where he discusses some topics from his book:

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

回答by Steven de Salas

Inheritance

遗产

I use a notation for inheritancethat is based on ExtJS 3, which I find works pretty close to emulating classical inheritance in Java. It basically runs as follows:

我使用基于ExtJS 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();

Namespaces

命名空间

I also agree with Eric Miraglia on sticking to namespaces so the code above should be run within its own context outside the window object, this is critical if you intend your code to run as one of many concurrent frameworks / libraries executing in the browser window.

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

This means that the only way to the window object is via your own namespace / module object:

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

// 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

})();

Interfaces

接口

You can also make use of more advances OOP constructs such as interfaces to enhance your application design. My approach to theseis to enhance the Function.prototypein order to get a notation along these lines:

您还可以利用更先进的 OOP 构造(例如接口)来增强您的应用程序设计。我对这些的方法是增强Function.prototype以获得沿这些线的符号:

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

OO Patterns

面向对象模式

As for 'Patterns' in the Java sense, I've only found use for the Singleton pattern(great for caching) and the Observer patternfor event-driven functionality such as assigning some actions when a user clicks on a button.

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

An example of utilising the Observer Pattern would be:

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

// 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');
});

And thats just a couple of tricks in my bag of OO JS, hope they are useful to you.

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

I recommend if you intend to go down this road that you read Douglas Crockfords Javascript: the Good Parts. Its a brilliant book for this stuff.

如果您打算走这条路,我建议您阅读 Douglas Crockfords Javascript: the Good Parts。这是一本关于这些东西的精彩书。

回答by Chris Laplante

I am a fan of the Module Pattern. It's a way of implementing extensible, non-dependent (most of the time) frameworks.

我是Module Pattern的粉丝。这是一种实现可扩展的、非依赖的(大多数情况下)框架的方式。

Example:

例子:

The framework, Q, is defined like this:

框架Q定义如下:

var Q = {};

To add a function:

添加函数:

Q.test = function(){};

These two lines of code are used together to form modules. The idea behind modules is that they all extend some base framework, in this case Q, but are not reliant on each other (if designed correctly) and can be included in any order.

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

In a module, you first create the framework object if it does not exist (which is an example of the Singletonpattern):

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

if (!Q)
    var Q = {};

Q.myFunction = function(){};

That way, you can have multiple modules (like the one above) in separate files, and include them in any order. Any one of them will create the framework object, and then extend it. No manual need to check if the framework exists. Then, to check if a module/function exists in custom code:

这样,您可以在单独的文件中包含多个模块(如上面的模块),并以任何顺序包含它们。他们中的任何一个都会创建框架对象,然后扩展它。无需手动检查框架是否存在。然后,检查自定义代码中是否存在模块/函数:

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

回答by Gordon Gustafson

The singleton pattern is often very helpful for 'encapsulation' and organization stuff. You can even change accesibility.

单例模式通常对“封装”和组织工作非常有帮助。您甚至可以更改可访问性。

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

cleanest way to implement a singleton in javascript

在 javascript 中实现单例的最简洁方法

回答by GSto

I really like jquery's method chaining pattern, allowing you to call several methods on one object. It makes it really easy to perform several operations in a single line of code.

我真的很喜欢 jquery 的方法链接模式,它允许您在一个对象上调用多个方法。它使得在一行代码中执行多个操作变得非常容易。

Example:

例子:

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

回答by Stefan Kendall

I really like the Decorator patternwith jQuery plugins. Rather than modifying plugins to meet your needs, write a custom plugin that just forwards requests and adds additional parameters and functionality.

我真的很喜欢带有 jQ​​uery 插件的装饰模式。与其修改插件以满足您的需求,不如编写一个仅转发请求并添加其他参数和功能的自定义插件。

For example, if you need to pass a set of default arguments around all the time, and you need slightly-different behavior that ties into business logic, write a plugin that does whatever preand postwork is necessary to suit your needs and passes your default arguments if those particular arguments aren't specified.

例如,如果你需要传递一组周围所有的时间默认参数,你需要稍微不同的行为关系到业务逻辑,写一个插件,做什么prepost工作是必要的,以满足您的需求,并通过您的默认参数如果未指定这些特定参数。

The main benefit of this is that you can update your libraries and not worry about porting library changes. Your code might break, but there's at least the chance that it won't.

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

回答by Matrix Buster

One of useful patterns in javascript world is chaining pattern which is made popular by LINQ at first place, and also is used in jQuery.

javascript 世界中一个有用的模式是链接模式,它首先被 LINQ 流行起来,也在 jQuery 中使用。

this pattern enables us to call different methods of a class in chaining manner.

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

the main structure of this pattern would be as

这种模式的主要结构将是

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);
    });

the key idea of this pattern is thiskey word, which makes possible accessing to other public member of Calculator fucntion.

该模式的核心思想是this关键字,这使得访问计算器功能的其他公共成员成为可能。