Javascript OOP最佳实践?

时间:2010-09-20 09:23:58

标签: javascript oop

我厌倦了在Javascript中看到几十种不同的面向对象编程方式。任何人都可以告诉我应该使用哪种技术,因为我想在大型项目上工作,我希望我的代码能够成为未来的证据吗?

9 个答案:

答案 0 :(得分:10)

这些只是我提出的一些快速指南,如果其他人有任何有意义的添加,我已将此答案设置为社区维基,因此您应该很容易编辑。

  1. 命名空间您的对象,以确保它们永远不会与第三方JavaScript库冲突。
    window['Andrew']['JS'] = {
        addEvent: function(el,evName) {/*Stuff*/},
        Rectangle: function(width,height) {/*Stuff*/}
    };
    那么你可以使用以下方法创建一个矩形对象:     
    var myRect = new Andrew.JS.Rectangle(14,11);
    然后,您的代码将永远不会干扰或受到任何其他人Rectangle的干扰
  2. 使用一致的命名策略,具体为:     
              
    • 对象名称应大写,其他所有内容(变量,函数)应以小写字符开头,即
      var myRect = new Andrew.JS.Rectangle(14,11);
      document.write(myRect.getArea());
              
    •         
    • 确保一切都有意义,即方法的动词,参数的名词+形容词。
    •     

  3. 确保所有方法和参数与其所属的对象相关。例如 在此示例中,可以使用inSquareFeet()方法将矩形区域转换为平方英尺。

    myRect.getAreaObject().inSquareFeet();
    确保inSquareFeet是getAreaObject()返回的对象的方法,而不是Andrew.JS.Rectangle的方法

  4. 使用构造函数,或者更具体地说,尝试尽可能地确保对象在构造后不需要进一步初始化,因此不是:
    var Person = function()
    {
        this.name = "";
        this.sayHello = function ()
        {
            alert(this.name + " says 'Hello!'");
            return this;
        }
    }
    
    var bob = new Person();
    bob.name = "Bob Poulton";
    bob.sayHello();
    尝试:
    var Person = function(name)
    {
        this.name = name;
        this.sayHello = function ()
        {
            alert(this.name + " says 'Hello!'");
            return this;
        }
    }
    
    var bob = new Person("Bob Poulton");
    bob.sayHello();

答案 1 :(得分:7)

我总是使用John resig:

http://ejohn.org/blog/simple-javascript-inheritance/

这很简单,不需要任何框架来运行。

答案 2 :(得分:1)

因为您正在开展大型项目,我建议使用像 mootools http://mootools.net/这样的javascript框架。

它具有良好的类和继承结构。

答案 3 :(得分:1)

我对OOP的理想对象就像使用带有原型的Instance方法:

示例:

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 Style架构时所走的道路。

答案 4 :(得分:1)

仅为了您的信息,我认为YUI提供了很少有关此主题的精彩教程

答案 5 :(得分:1)

//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() { }
    }
}

它的优势在于它自动初始化Global对象,允许您维护代码的完整性,并根据您的定义将每个功能组织到特定的分组中。

这种结构是可靠的,提供了所有你期望从OOP中获得的基本句法事物而没有关键词。

甚至还有一些巧妙的方法来设置接口。如果你选择那么远,a simple search会给你一些很好的教程和提示。

使用javascript和visual studio进行setting up intellisense is possible,然后定义每个部分并引用它们,这使得编写javascript更清晰,更易于管理。

根据您的情况需要使用这三种方法有助于保持全局命名空间的清洁,保持代码的组织并保持每个对象的关注点分离..如果使用正确的话。请记住,如果不使用对象背后的逻辑,面向对象设计是没有用的!

答案 6 :(得分:0)

我使用这样的模式并建议您也使用它:

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.') 

答案 7 :(得分:0)

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,因为很多原因,它不是那么好的语言。认为方案有波浪括号和分号,你将开始像专业人士那样编写语言。话虽如此,有时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;
}

这使得事情变得更加复杂,但是在仍然采用OO概念的功能方法(在这种情况下,使用装饰器函数而不是真正的继承)的同时实现了期望的最终结果。我对整个方法的喜欢之处在于,我们仍然按照这种语言的方式处理对象 - 可以随意附加内容的属性包。

另一个注意事项是,这与你在大多数工作中大部分时间都会看到的情况截然不同,往往很难解释a)发生了什么,以及b)为什么会这样对同事来说是一个好主意。

答案 8 :(得分:-2)

您可以尝试使用简单,有用且快速的对象:

var foo = {
    foo1: null,
    foo2: true,
    foo3: 24,
    foo4: new Array(),

    nameOfFunction1: function(){
      alert("foo1");
    },

    nameOfFunction2: function(){
      alert("foo2");
    },
}

要使用它,您必须创建此对象的实例并使用类似java中的对象:

foo.nameOfFunction2();

您也可以查看指向其他解决方案的链接:http://www.javascriptkit.com/javatutors/oopjs.shtml

我希望能回答你的问题。