Mah*_*aha 5 javascript design-patterns factory-pattern
Parasitic Constructor Pattern可以看作是工厂和构造函数模式的组合.在工厂模式中,我们调用一个函数,然后显式创建一个对象,并向对象添加所需的属性和方法,最后返回该对象.
function createPerson(name, age, job){
var o = new Object(); //explicit object creation
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var person1 = createPerson(“Nicholas”, 29, “Software Engineer”);
var person2 = createPerson(“Greg”, 27, “Doctor”);
Run Code Online (Sandbox Code Playgroud)
注意事项:
new运算符的方法被调用缺点:它不允许识别对象的类型.
通过使用new运算符调用任何函数都可以将其视为构造函数.当没有new操作符调用时,在函数内部,this对象指向全局对象(window在浏览器中).当使用new运算符调用函数时,它首先创建新实例,object然后将this对象设置为新创建的对象.
构造函数模式向this对象添加方法和属性,最后返回this对象,从而允许稍后使用instanceOf运算符标识对象的类型.
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person(“Nicholas”, 29, “Software Engineer”);
var person2 = new Person(“Greg”, 27, “Doctor”);
Run Code Online (Sandbox Code Playgroud)
注意事项:
new运算符调用函数(使JavaScript引擎将其视为构造函数)this返回对象现在Parasitic Constructor Pattern显式创建并返回一个类似于工厂模式的对象,并使用new运算符调用构造函数模式:
function Person(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var friend = new Person(“Nicholas”, 29, “Software Engineer”);
friend.sayName(); //”Nicholas”
Run Code Online (Sandbox Code Playgroud)
但是,我无法看到使用new运算符调用该函数.我的意思是,因为函数显式创建并返回对象,所以我们无法使用instanceOfoperator 显式地标识对象类型.
那么Parasitic Constructor模式有什么好处呢?是否有任何可以被利用或适用于特定对象创建场景的技术细微之处?或者只是另一种可能的编程方法来创建对象?
我认为从你的角度来看,没有太大区别,但是如果你更进一步并实现抽象工厂模式,或者你开始对工厂进行多态化,那么每次编写新的工厂时,你都可以节省大量工作一。
\n\n在 javascript 中,由于该语言没有私有值,因此您可以为对象设置任何值,因此如果您使用支持对象 OOP 标准的框架,工厂可以非常强大,并且可以从基类继承大部分逻辑。
\n\n编辑
\n\n好吧,在我看来,当涉及到 JavaScript 和这些模式时,最重要的一件事就是原型设计。
\n\n原型设计基本上是在 javascript 中定义对象的方式,因此运行时实际上可以识别该对象并可以将其与其他对象区分开来。
\n\n基本上只使用原型看起来像这样:
\n\nvar Person = function(name){\n this.name = name\n}; //constructor\nPerson.prototype.constructor = Person;\nPerson.prototype.name = \'Dave\';\nPerson.prototype.getName = function() {\n return this.name;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n一些测试代码:
\n\nvar dave = new Person(\'Dave\');\nconsole.log(dave.getName());\xe2\x80\x8b\nRun Code Online (Sandbox Code Playgroud)\n\n最后是一个工厂:
\n\nvar PersonFactory = function(name) {\n return new Person(name);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n现在,该注释的问题通常是它的可维护性很差并且没有继承性。
\n\n现在大多数框架的目的是:\n您可以创建构建原型的辅助函数,甚至构建原型链。基本上,您定义一个接受另一个对象的对象,并将其他对象成员解析为所需类对象的原型,从而为继承等留下了各种可能性。
\n\n一些示例可以在这里找到:\n http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures
\n\n我喜欢 mootools 处理类的方式:
\n\nvar MyClass = new Class({\nExtends: MyOtherClass\nImplements: [MyInterface, MyOtherInterface],\n\nmyPublicValue: null,\nmyOtherValue: null,\n\n\ninitialize: function() {\n //constructor\n},\n\ndoStuff: function() {\n return \'stuff done\';\n}\n\n});\nRun Code Online (Sandbox Code Playgroud)\n\nmootools 类系统本身的缺点:\n-Closure 编译器不喜欢尾随逗号,您倾向于将它们留在代码中
\n\n-几乎没有 IDE 支持 mootools 类的自动完成(因为原型没有在文件中注释,可以使用脚本将类解析为原型文件来解析)
\n\n现在有了这个,您可以选择大量的设计决策,让您的工厂从您自己的原型辅助类继承,使用原型辅助类来创建实际的工厂(这里有一些递归),您可以在创建时解析每个对象(类似于延迟加载)或解析页面加载时的每个类对象(请小心,如果您进入继承,在大多数实现中,您派生的类必须首先解析)\也不采取任何可能的方式。
\n\n我希望这对你有帮助:)
\n\n(抱歉我现在的英语不好,我今晚很累xD)
\n| 归档时间: |
|
| 查看次数: |
903 次 |
| 最近记录: |