您在应用程序的javascript中使用了哪些面向对象的设计模式,为什么?
即使没有附加正式的设计模式,也可以随意发布代码。
我已经写了很多javascript,但是我还没有将很多面向对象的模式应用到我正在做的事情上,而且我确信我错过了很多。
答案 0 :(得分:53)
以下是三种流行的JavaScript模式。由于closures:
,这些很容易实现您可能还想查看:
以下是Diaz提出的2008年Google I / O演讲,他在书中讨论了一些话题:
答案 1 :(得分:25)
<强>继承强>
我使用基于notation for inheritance的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();
<强>命名空间强>
我同意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 () {
// ...
}
};
答案 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
关键词,这使得访问计算机功能的其他公共成员成为可能。