开发者

Javascript OOP best practices? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance. Closed 9 years ago.

I'm sick of seeing dozens of different ways of doing object oriented programming in Javascript. Can anyone just tell me which technique I should use considering I want to work on a lar开发者_Python百科ge scale project and I want my code to be future proof?


These are just a few quick guidelines I've come up with, if anyone else has anything meaningful to add, I've set this answer as a community wiki so it should be easy enough for you to edit.

  1. Namespace your objects to ensure they will never conflict with third party JavaScript libraries.
    window['Andrew']['JS'] = {
        addEvent: function(el,evName) {/*Stuff*/},
        Rectangle: function(width,height) {/*Stuff*/}
    };
    So then you would create a rectangle object by using:
    var myRect = new Andrew.JS.Rectangle(14,11);
    And then your code will never interfere with, or be interfered by anybody else's Rectangle.

  2. Use a consistent naming strategy, specifically:
    • Object names should be capitalized, everything else (variables, functions) should begin with a lower case character i.e.
      var myRect = new Andrew.JS.Rectangle(14,11);
      document.write(myRect.getArea());
    • Ensure everything is meaningful, i.e. verbs for methods, nouns + adjectives for parameters.

  3. Make sure all methods and parameters are relevant to the object they belong to. e.g. In this example, the area of the rectangle can be converted to square feet using the method inSquareFeet().

    myRect.getAreaObject().inSquareFeet();
    Make sure inSquareFeet is a method of the object returned by getAreaObject() and not a method of Andrew.JS.Rectangle

  4. Use constructors, or more specifically, try as hard as possible to make sure that an object doesn't need any further initialization to be used once it has been constructed, so instead of:
    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();
    try:
    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();


I always use John resig's:

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

It's simple and doesn't require any frameworks to function.


Because you are working on a large scale project i would suggestion a javascript framework like mootools http://mootools.net/.

It has a good class and inheritance structure.


My ideal Object for OOP is like using an Instance method with prototypes:

Example:

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

Then I would always use like:

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.

And that's the kind of road i go down when it comes to building a JavaScript OO Style architecture.


just for your information, i think YUI provides few great tutorials on this topic


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

The strength to this is that it initializes the Global object automatically, allows you to maintain the integrity of your code, and organizes each piece of functionality into a specific grouping by your definition.

This structure is solid, presenting all of the basic syntactical things you would expect from OOP without the key words.

There are even some ingenious ways to set up interfaces as well. If you choose to go that far, a simple search will give you some good tutorials and tips.

Even setting up intellisense is possible with javascript and visual studio, and then defining each piece and referencing them makes writing javascript cleaner and more manageable.

Using these three methods as needed by your situation helps keep the global namespace clean, keep your code organized and maintains separation of concerns for each object.. if used correctly. Remember, Object Oriented Design is of no use if you don't utilize the logic behind using objects!


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()

This is a functional approach, and has a great deal more going for it (such as encapsulation) then anything else you are going to see

In a general way, you shouldn't be doing OO in javascript, it isn't that great a language for it for a great many reasons. Think scheme with squiggly brackets and semi-colons, and you will start writing the language like the pros do. That being said, sometime OO is a better fit. In those cases, the above is typically the best bet

to bring inheritance into the mix

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

This makes things a tad more complected, but accomplishes the desired end result while still taking a functional approach to OO concepts (in this case, using decorator functions instead of real inheritance). What I like about the whole approach is we are still really treating objects the way they are intended to be in this kind of language -- a property bag you can attach stuff to at will.

Another note is this is wildly different then what you will see most of the time in most of the jobs you will ever work at, and often is very hard to explain a) what is going on, and b) why it is a good idea to coworkers.


I use such a pattern and recommend to you to use it too:

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


You can try with a simple, usefull and quick object:

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

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

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

To use this, you have to create an instance of this object and use like a object in java:

foo.nameOfFunction2();

Also you can check this link to other solution: http://www.javascriptkit.com/javatutors/oopjs.shtml

I hope that answer your question.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜