Javascript OOP最佳实践?
我厌倦了在Javascript中看到几十种不同的面向对象编程方法。有谁能告诉我,考虑到我想在一个大型项目上工作,并且我希望我的代码能够经得起未来的考验,我应该使用哪种技术?这些只是我提出的一些快速指南,如果其他人有什么有意义的补充,我已经将这个答案设置为一个社区wiki,这样你就可以很容易地编辑它Javascript OOP最佳实践?,javascript,oop,Javascript,Oop,我厌倦了在Javascript中看到几十种不同的面向对象编程方法。有谁能告诉我,考虑到我想在一个大型项目上工作,并且我希望我的代码能够经得起未来的考验,我应该使用哪种技术?这些只是我提出的一些快速指南,如果其他人有什么有意义的补充,我已经将这个答案设置为一个社区wiki,这样你就可以很容易地编辑它 为对象命名名称空间,以确保它们永远不会与第三方JavaScript库冲突。 window['Andrew']['JS'] = { addEvent: function(el,evName) {
inSquareFeet()
尝试:
var Person=函数(名称)
{
this.name=名称;
this.sayHello=函数()
{
警报(this.name+“说‘你好’”);
归还这个;
}
}
var bob=新人(“bob Poulton”);
鲍勃:你好;
您可以尝试使用简单、有用且快速的对象:
var foo = {
foo1: null,
foo2: true,
foo3: 24,
foo4: new Array(),
nameOfFunction1: function(){
alert("foo1");
},
nameOfFunction2: function(){
alert("foo2");
},
}
要使用它,您必须创建此对象的实例,并像java中的对象一样使用:
foo.nameOfFunction2();
此外,您还可以查看此链接以找到其他解决方案:
我希望这能回答您的问题。因为您正在从事一个大型项目,我建议您使用类似于mootools的javascript框架
它有一个很好的类和继承结构。我使用这种模式,并建议您也使用它:
function Person(firstname, lastname, age)
{
var self = this;
var _ = {};
// Private members.
var firstname = firstname;
var lastname = lastname;
var age = age || 'unknown';
// Private methods.
function first_letter_to_uppercase(str) {
return str.charAt(0).toUpperCase() + str.substr(1);
}
// Public members and methods.
_.get_age = function()
{
return age;
}
_.get_name = function()
{
return first_letter_to_uppercase(firstname) + ' ' +
first_letter_to_uppercase(lastname);
}
return _;
}
var p = new Person('vasya', 'pupkin', 23);
alert("It's " + p.get_name() + ', he is ' + p.get_age() + ' years old.')
我理想的OOP对象类似于对原型使用实例方法: 例如:
var Users = function()
{
var _instance;
this.prototype.getUsername = function(){/*...*/}
this.prototype.getFirstname = function(){/*...*/}
this.prototype.getSecurityHash = function(){/*...*/}
/*...*/
/*Static Methods as such*/
return { /*Return a small Object*/
GetInstance : function()
{
if(_instance == null)
{
_instnance = new Users(arguments);
}
return _instnance; //Return the object
},
New: function()
{
_instnance = null; //unset It
return this.GetInstnace(arguments);
}
}
}
然后我会一直使用这样的方法:
Firstname = Users.GetInstance('Robert','Pitt').getFirstname();
Username = Users.GetInstance().getUsername(); //Returns the above object.
Me = Users.New('Robert',null); //Deletes the above object and creates a new instance.
Father = Users.New('Peter','Piper'); //New Object
Me.AddFather(Father); //Me Object.
这就是我在构建JavaScript OO风格体系结构时所走的道路。仅供参考,我认为在这个主题上提供了一些很好的教程我总是使用John resig的: 它很简单,不需要任何框架即可运行
function foo() {
var bar = function() { console.log("i'm a private method"); return 1; };
var iAmAPrivateVariable = 1;
return {
publicMethod: function() { alert(iAmAPrivateVariable); },
publicVariable: bar()
}
}
//usage
var thing = foo()
这是一种功能性的方法,它比您将要看到的任何其他方法都更适合(比如封装)
一般来说,你不应该用javascript做OO,因为有很多原因,它不是一种很好的语言。考虑一下带有弯曲括号和分号的scheme,您将开始像专业人员一样编写该语言。也就是说,有时候OO更合适。在这些情况下,上述情况通常是最佳选择
将继承纳入混合
function parent() {
return { parentVariable: 2 };
}
function foo() {
var bar = function() { console.log("i'm a private method"); return 1; };
var iAmAPrivateVariable = 1;
me = parent();
me.publicMethod = function() { alert(iAmAPrivateVariable); };
me.publicVariable = bar();
return me;
}
这使事情变得更加复杂,但在仍然采用面向对象概念的函数方法(在本例中,使用decorator函数而不是真正的继承)的情况下实现了期望的最终结果。我喜欢整个方法的一点是,我们仍然在以这种语言的方式处理对象——一个可以随意附加内容的属性包
另一个值得注意的是,这与你在大多数工作中看到的情况大不相同,通常很难解释a)发生了什么,b)为什么这对同事来说是个好主意 //创建和定义全局命名空间对象
//Create and define Global NameSpace Object
( function(GlobalObject, $, undefined)
{
GlobalObject.Method = function()
{
///<summary></summary>
}
GlobalObject.Functionality = {};
}) (GlobalObject = GlobalObject || {}, jQuery);
//New object for specific functionality
( function(Events, $, undefined)
{
//Member Variables
var Variable; // (Used for) , (type)
// Initialize
Events.Init = function()
{
///<summary></summary>
}
// public method
Events.PublicMethod = function(oParam)
{
///<summary></summary>
///<param type=""></param>
}
// protected method (typically define in global object, but can be made available from here)
GlobalObject.Functionality.ProtectedMethod = function()
{
///<summary></summary>
}
// internal method (typically define in global object, but can be made available from here)
GlobalObject.InternalMethod = function()
{
///<summary></summary>
}
// private method
var privateMethod = function()
{
///<summary></summary>
}
}) (GlobalObject.Funcitonality.Events = GlobalObject.Funcitonality.Events || {}, jQuery )
// Reusable "class" object
var oMultiInstanceClass = function()
{
// Memeber Variables again
var oMember = null; //
// Public method
this.Init = function(oParam)
{
oMember = oParam;
for ( n = 1; i < oMemeber.length; i += 1 )
{
new this.SubClass.Init(oMember[i]); // you get the point, yeah?
}
}
this.Subclass = function()
{
this.Init = function() { }
}
}
(函数(全局对象,$,未定义)
{
GlobalObject.Method=函数()
{
///
}
GlobalObject.Functionality={};
})(GlobalObject=GlobalObject | |{},jQuery);
//用于特定功能的新对象
(函数(事件,$,未定义)
{
//成员变量
var变量;/(用于),(类型)
//初始化
Events.Init=函数()
{
///
}
//公共方法
Events.PublicMethod=函数(oParam)
{
///
///
}
//受保护的方法(通常在全局对象中定义,但可以在此处使用)
GlobalObject.Functionary.ProtectedMethod=函数()
{
///
}
//内部方法(通常在全局对象中定义,但可以在此处使用)
GlobalObject.InternalMethod=函数()
{
///
}
//私有方法
var privateMethod=函数()
{
///
}
})(GlobalObject.functionality.Events=GlobalObject.functionality.Events | |{},jQuery)
//可重用的“类”对象
var oMultiInstanceClass=函数()
{
//又是Memeber变量
var oMember=null;//
//公共方法
this.Init=函数(oParam)
{
oMember=oParam;
对于(n=1;i
这样做的优势在于它自动初始化全局对象,允许您保持代码的完整性,并根据您的定义将每一项功能组织到一个特定的分组中
这个结构是坚实的,它提供了OOP所期望的所有基本语法,而没有关键词
甚至还有一些巧妙的方法来设置接口。如果你选择走那么远,我会给你一些很好的教程和提示
即使使用javascript和visualstudio,然后定义每一部分并引用它们也会使编写javascript更干净、更易于管理
根据您的情况使用这三种方法有助于保持全局名称空间的整洁,保持代码的组织,并保持每个对象关注点的分离。。如果使用正确。记住,如果你不利用使用对象背后的逻辑,面向对象的设计是没有用的 可能的重复我喜欢已经有三个不同的Javascript OO符号作为这个问题的答案,而问题是提供一个OP应该使用的单一符号。有各种不同的符号-我认为,为了清楚起见,每种符号的优点和缺点
var Users = function()
{
var _instance;
this.prototype.getUsername = function(){/*...*/}
this.prototype.getFirstname = function(){/*...*/}
this.prototype.getSecurityHash = function(){/*...*/}
/*...*/
/*Static Methods as such*/
return { /*Return a small Object*/
GetInstance : function()
{
if(_instance == null)
{
_instnance = new Users(arguments);
}
return _instnance; //Return the object
},
New: function()
{
_instnance = null; //unset It
return this.GetInstnace(arguments);
}
}
}
Firstname = Users.GetInstance('Robert','Pitt').getFirstname();
Username = Users.GetInstance().getUsername(); //Returns the above object.
Me = Users.New('Robert',null); //Deletes the above object and creates a new instance.
Father = Users.New('Peter','Piper'); //New Object
Me.AddFather(Father); //Me Object.
function foo() {
var bar = function() { console.log("i'm a private method"); return 1; };
var iAmAPrivateVariable = 1;
return {
publicMethod: function() { alert(iAmAPrivateVariable); },
publicVariable: bar()
}
}
//usage
var thing = foo()
function parent() {
return { parentVariable: 2 };
}
function foo() {
var bar = function() { console.log("i'm a private method"); return 1; };
var iAmAPrivateVariable = 1;
me = parent();
me.publicMethod = function() { alert(iAmAPrivateVariable); };
me.publicVariable = bar();
return me;
}
//Create and define Global NameSpace Object
( function(GlobalObject, $, undefined)
{
GlobalObject.Method = function()
{
///<summary></summary>
}
GlobalObject.Functionality = {};
}) (GlobalObject = GlobalObject || {}, jQuery);
//New object for specific functionality
( function(Events, $, undefined)
{
//Member Variables
var Variable; // (Used for) , (type)
// Initialize
Events.Init = function()
{
///<summary></summary>
}
// public method
Events.PublicMethod = function(oParam)
{
///<summary></summary>
///<param type=""></param>
}
// protected method (typically define in global object, but can be made available from here)
GlobalObject.Functionality.ProtectedMethod = function()
{
///<summary></summary>
}
// internal method (typically define in global object, but can be made available from here)
GlobalObject.InternalMethod = function()
{
///<summary></summary>
}
// private method
var privateMethod = function()
{
///<summary></summary>
}
}) (GlobalObject.Funcitonality.Events = GlobalObject.Funcitonality.Events || {}, jQuery )
// Reusable "class" object
var oMultiInstanceClass = function()
{
// Memeber Variables again
var oMember = null; //
// Public method
this.Init = function(oParam)
{
oMember = oParam;
for ( n = 1; i < oMemeber.length; i += 1 )
{
new this.SubClass.Init(oMember[i]); // you get the point, yeah?
}
}
this.Subclass = function()
{
this.Init = function() { }
}
}