The Ultimate Guide to Object Oriented Basics of JavaScript

Posted in Web Design • Posted on 18 Comments

Thanks to expertly crafted libraries such as jQuery and MooTools, JavaScript has become a foundation of Front-End Development. However, it’s extremely important that we note the higher level concepts utilized in these wonderful libraries. Why is that? As web developers, we must equally balance learning the current programming trends with attempts to push the boundaries of those trends. Without this balance, no innovation will occur in web development. So let’s take a moment to appreciate the fundamentals of JavaScript Object Oriented Programming, which include classes, inheritance, and scope.

Classes

Before we learn how to implement classes into your code, let’s discuss what classes are and why you should bother learning/using them.

As stated in the Java documentation, “A class is the blueprint from which individual objects are created.” Consider an actual blueprint used in the process of making a house. The builders use the blueprint to evaluate what properties the house contains and what functions the house will execute. Classes are a convenient way to represent the properties of objects, be it a house, car, or person. Classes become especially useful when more than one of a given object exists.

As an example, let’s compare two real-life objects without the use of classes. This mirrors the procedural thought process as opposed to the object oriented thought process. We’ll describe a man named Rob and a baby girl named Emillee. We must assume we know nothing about the human body since we have no blueprint(class) to work from.

Rob:

  1. Rob has two oval-like structures a few inches apart on the upper portion of his body. These oval like structures have a white background with a brown middle.
  2. Rob has two structures that run relatively parallel to the floor that seem to indicate the most vertical portion of the body that’s still part of the body’s base.
  3. Rob has two appendages that extend from another two appendages. These seem to be used to grab items. They seem relatively large.
  4. Rob measures approximately 6 feet in height.
  5. Rob involuntarily intakes oxygen and converts it into Carbon Dioxide.

Emilee:

  1. Emillee has two oval-like structures a few inches apart on the upper portion of her body. These oval like structures have a white background with a blue middle.
  2. Emillee has two structures that run relatively parallel to the floor that seem to indicate the most vertical portion of the body that’s still part of the body’s base.
  3. Emillee has two appendages that extend from another two appendages. These seem to be used to grab items. They seem relatively small.
  4. Emillee measures approximately 1.5 feet in height.
  5. Emillee involuntarily intakes oxygen and converts it into Carbon Dioxide.

That was a LOT of work to just describe a human’s 1) Eyes, 2) Shoulders, 3) Hands, 4) Height, and 5) Act of Breathing. Notice we had to make almost the exact same observations both times since we had no blueprint to work from. While describing 2 people wasn’t too bad, what if we wanted to describe 100, 1000, a million? There certainly has to be a more efficient way of describing objects that have similar properties: This is where classes shine.

Let’s rethink the previous example using an object oriented mindset. Since we are describing a man and a baby girl, we know they are both humans. So let’s first create a simple blueprint for humans.

Humans:

  1. Have two oval-like structures a few inches apart on the upper portion of his body. These oval like structures have a white background with a varying color in the middle. We call them eyes.
  2. Have two structures that run relatively parallel to the floor that seem to indicate the most vertical portion of the body that’s still part of the body’s base. We call them shoulders.
  3. Have two appendages that extend from another two appendages. These seem to be used to grab items. Their size varies. We call them hands.
  4. Vary in height depending on age and other factors. We call this height.
  5. Involuntarily intake oxygen and convert it into Carbon Dioxide. We call this breathing.

So we’ve stated that the properties of humans are that they have eyes, shoulders, hands, and a height. We’ve also stated that these properties may vary. Having defined the blueprint of a Human, and having declared that Rob and Emillee are human, we can apply what we already know about humans to Rob and Emillee.

Rob is a Human.

  1. Rob has brown eyes
  2. Rob has shoulders
  3. Rob has large hands
  4. Rob is 6 feet tall
  5. Rob breathes

Emillee is a Human.

  1. Emillee has blue eyes
  2. Emillee has shoulders
  3. Emillee has small hands
  4. Emillee is 1.5 feet tall
  5. Emillee breathes

By explicitly stating Rob and Emillee are Human, we take the properties and functions associated with being Human and apply them directly to Rob and Emillee. This lets us avoid redefining all the body parts while also letting us effectively describe the key differences between the two objects.

Here are a few examples of classes and their objects(known as instances of the class) so you understand the relationship between the two.

Class Student

  • Properties: grades, age, date of birth, SSID
  • Functions: calculate GPA, view absences, update conduct

Class Employee

  • Properties: EIN, hourly wage, contact number, insurance
  • Functions: set wage, view productivity, pull resume

Class Computer

  • Properties: CPU, motherboard, monitor
  • Functions: turn on, turn off, restart

So now that we understand the idea behind classes, let’s apply what we know to JavaScript. Unlike languages including PHP and C++, JavaScript does not have the class data type. However, using JavaScripts flexibility, we can easily mimic a class using functions.

Referring to one of our previous examples, let’s use a class to represent students.

When creating a class, there are two things you must do: You must know what properties/functions(also known as methods) the class will have, and you need to initialize the properties with a value.

	function Student(name, gender, age, grade, teacher)
	{
		this.name = name;
		this.gender = gender;
		this.age = age;
		this.grade = grade;
		this.teacher = teacher;
	}

	var bob = new Student("bob", "male", 15, 10, "Marlow");
	alert(bob.age); //Outputs 15

	var susan = new Student("susan", "female", 10, 5, "Gresham");
	alert(susan.gender); //Outputs 'female'

From this example we can see that instances of the class are initiated using the new operator. Properties and methods of the class are accessed using the . (dot) operator. So to get the property age of the instance of the Student class named bob, we simply use bob.age. Similarly, we created an instance of the Student class and assigned that to susan. To get the gender of susan, we simply use susan.gender. The code readability benefits from classes are enormous: You can reason that bob.age is the age of bob without having any programming experience.

However, the previous example contains two detrimental (but easily fixable) flaws.
1) The class properties can be accessed by any statement
2) The arguments must be passed in a certain order

Keeping property values private

Note that in the previous example, we were able to get the value of bob.age by simply calling bob.age. Additionally, we could set bob.age to any value we feel like anywhere in the program.

	var bob = new Student("bob", "male", 15, 10, "Marlow");
	alert(bob.age); //Outputs 15

	bob.age = 9;
	alert(bob.age); //Outputs 9;

Seems harmless, right? Well, consider this example.

	var bob = new Student("bob", "male", 15, 10, "Marlow");
	alert(bob.age); //Outputs 15

	bob.age = -50;
	alert(bob.age); //Outputs -50;

We have age as a negative number: A logical inconsistency. We can prevent issues like this and preserve the integrity of our data by utilizing the concept of private variables. A private variable is a variable that can only be accessed within the class itself. While once again JavaScript does not have a reserve word for making a variable private, JavaScript gives us the tools to create the same effect.

	function Student(name, gender, age, grade, teacher)
	{
		var studentName = name;
		var studentGender = gender;
		var studentGrade = grade;
		var studentTeacher = teacher;
		var studentAge = age;

		this.getAge = function()
		{
			return studentAge;
		};

		this.setAge = function(val)
		{
			studentAge = Math.abs(val); //Keep age positive using absolute value
		};
	}

	var bob = new Student("bob", "male", 15, 10, "Marlow");
	alert(bob.studentAge); //undefined, since age is privately protected in the class definition

	alert(bob.getAge()); //Outputs 15
	bob.setAge(-20);
	alert(bob.getAge()); //Outputs 20

By using variable declarations as opposed to attributing properties directly to the class, we have protected the integrity of our age data. Since JavaScript utilizes function scope, a variable declared within our class will not be made accessible outside of that class unless explicitly returned by a function within the class. The method this.getAge, which returns the student age to the calling environment, is known as an Accessor method. An Accessor method returns the value of a property so that the value can be used outside the class without affecting the value inside the class. Accessor methods are usually preceded with the word “get” by convention. The method this.setAge is known as a Mutation method. Its purpose is to alter the value of a property and preserve its integrity.

So we see the benefits of using Accessor and Mutation methods within a class to preserve the integrity of data. However, creating an Accessor method for each property creates extremely long-winded code.

	function Student(name, gender, age, grade, teacher)
	{
		var studentName = name;
		var studentGender = gender;
		var studentGrade = grade;
		var studentTeacher = teacher;
		var studentAge = age;

		this.getName = function()
		{
			return studentName;
		};

		this.getGender = function()
		{
			return studentGender;
		};

		this.getGrade = function()
		{
			return studentGrade;
		};

		this.getTeacher = function()
		{
			return studentTeacher;
		};

		this.getAge = function()
		{
			return studentAge;
		};

		this.setAge = function(val)
		{
			studentAge = Math.abs(val); //Keep age positive using absolute value
		};
	}

	var bob = new Student("bob", "male", 15, 10, "Marlow");
	alert(bob.studentGender); //undefined, since gender is privately protected in the class definition

	alert(bob.getGender()); //Outputs 'male'

My C++ Professor always said “If you find yourself typing the same code over and over, you’re doing it wrong.” Indeed there is a more efficient way to create Accessor methods for each property. Additionally, this mechanism also eliminates the need to call function arguments in a specific order.

Dynamically Generated Accessor methods

This demonstration is based off John Resig’s Pro JavaScript Techniques book (which I highly encourage you to read. The first 3 chapters alone are worth it).

	function Student( properties )
	{
		var $this = this;  //Store class scope into a variable named $this

		//Iterate through the properties of the object
		for ( var i in properties )
		{

			(function(i)
			{
				// Dynamically create an accessor method
				$this[ "get" + i ] = function()
				{
					return properties[i];
				};
			})(i);
		}
	}

	// Create a new user object instance and pass in an object of
	// properties to seed it with
	var student = new Student(
	{
		Name: "Bob",
		Age: 15,
		Gender: "male"
	});

	alert(student.name); //Undefined due to the property being private

	alert(student.getName()); //Outputs "Bob"
	alert(student.getAge()); //Outputs 15
	alert(student.getGender()); //Outputs "male"

By implementing this technique, not only do we keep our properties private, we avoid the need to specify our arguments in order. The following class instantiations are all equivalent

	var student = new Student(
	{
		Name: "Bob",
		Age: 15,
		Gender: "male"
	});

	var student = new Student(
	{
		Age: 15,
		Name: "Bob",
		Gender: "male"
	});

	var student = new Student(
	{
		Gender: "male",
		Age: 15,
		Name: "Bob"
	});

Inheritance

Recall that throughout this article I’ve used the term “class” extremely loosely. As stated before, JavaScript has no class entity, but the pattern of classes can still be followed. The main difference between JavaScript and other object oriented languages lies in their inheritance models. C++ and Java exhibit Class-based or “Classical” inheritance. JavaScript, on the other hand, exhibits Prototypal Inheritance. In other object oriented languages, class is an actual data type that represents the blueprint for creating objects. In JavaScript, although we can use Functions to simulate an object blueprint, they are just in fact objects themselves. These objects are then used as models (aka prototypes) for other objects.(See Article JavaScript Prototypal Inheritance).

Applying the concept of prototypal inheritance allows us to create “subclasses”, or objects that inherit the properties of another object. This becomes particularly useful when we want to use the methods of another object with some slight modifications.

Consider a class Employee. Let’s say we have two types of employees: wage-based and commission-based. These employee types will have many similar properties. For example, regardless of whether an employee receives income through commission or receives income through wages, an employee will have a name. However, the way the income for a commission-based employee and a wage-based employee is completely different. The following example captures this idea.

	function Worker()
	{
		this.getMethods = function(properties, scope)
		{
			var $this = scope;  //Store class scope into a variable named $this

			//Iterate through the properties of the object
			for ( var i in properties )
			{

				(function(i)
				{
					// Dynamically create an accessor method
					$this[ "get" + i ] = function()
					{
						return properties[i];
					};

				//Dynamically create a mutation method that parses for an integer and
				//Ensures it is positive.
				$this[ "set" + i ] = function(val)
				{
					if(isNaN(val))
					{
						properties[i] = val;
					}
					else
					{
						properties[i] = Math.abs(val);
					}
				};
				})(i);
			}
		};
	}

	//The CommissionWorker "subclass" and WageWorker "subclass"
	//inherit the properties and methods of Worker.
	CommissionWorker.prototype = new Worker();
	WageWorker.prototype = new Worker();

	function CommissionWorker(properties)
	{
		this.getMethods(properties, this);

		//Calculates income
		this.getIncome = function()
		{
			return properties.Sales * properties.Commission;
		}
	}

	//Expects the following properties: wage, hoursPerWeek, weeksPerYear
	function WageWorker(properties)
	{
		this.getMethods(properties, this);

		//Calculates income
		this.getIncome = function()
		{
			return properties.Wage * properties.HoursPerWeek * properties.WeeksPerYear;
		}
	}

	var worker = new WageWorker(
	{
		Name: "Bob",
		Wage: 10,
		HoursPerWeek: 40,
		WeeksPerYear: 48
	});

	alert(worker.wage); //Undefined. wage is a private property.

	worker.setWage(20);
	alert(worker.getName());   //Outputs "Bob"
	alert(worker.getIncome()); //Outputs 38,400 (20*40*48)

	var worker2 = new CommissionWorker(
	{
		Name: "Sue",
		Commission: .2,
		Sales: 40000
	});
	alert(worker2.getName());   //Outputs "Sue"
	alert(worker2.getIncome()); //Outputs 8000 (2% times 40,000)

The most important statements from the previous example are:

CommissionWorker.prototype = new Worker();
WageWorker.prototype = new Worker();

This states that for each instance of a new CommissionWorker or a new WageWorker object, the properties and methods of Worker will be passed down to those new objects. These methods and properties can be overwritten within the “subclass” definition if so desired.

Scope

JavaScript exhibits what is known as function scope. This means variables declared in a function are not initially accessible outside the function from which they originate. However, in blocks (such as coniditonal statements), variable declarations or alterations are made available to the calling environment.

	var car = "Toyota";

	if(car == "Toyota")
	{
		car = "Toyota - We never stop...and you won't either.";
	}

	alert(car); //Ouputs Toyota - We never stop...and you won't either.

	car = "Toyota"; //Reset car back to original value.

	function makeFord(car)
	{
		car = "Ford";
	}

	makeFord(car);
	alert(car); //Outputs "Toyota" because car was altered in the function scope.

However, if you want a function to alter the value, you can pass in an object as an argument and alter a property of the object.

	var car = new Object();
	car.brand = "Toyota"

	function makeFord(car)
	{
		car.brand = "Ford";
	}

	makeFord(car);

	alert(car.brand); //Outputs "Ford"

This is known as passing a value to a function “by reference”. I generally recommend passing by reference only if you are setting up methods within a class and you know what properties the object will contain.

You are now armed with the object oriented basics as applied to JavaScript. Use these principles to simplify your code for projects in the future.

1 Written ArticlesWebsite

Joseph McCullough is the lead developer of Vert Studios, a web design company located in Tyler, Texas. Check out the Vert Studios Blog for articles on web development and design. Follow me on Twitter! @Joe_Query

18 Comments Best Comments First
  • Aldian

    Friday, October 1st, 2010 17:18

    8

    If my prototypical public methods need to access private attribute then I need to create the get/set mutator for that attribute. By creating getters and setters then I open the way for outside code to change my private attributes.
    Is there a way to enforce that only my prototypical public methods accessible from the outside world, but not my mutators?

    +1
    • Joseph McCullough

      Monday, October 4th, 2010 10:28

      14

      Yup, there sure is! Take this as a starting point, feel free to tweak as you see fit. Also, you can email me at joseph@vertstudios.com if you have any more questions!

      function Worker()
      {
      this.getAccessorMethods = function(properties, scope)
      {
      var $this = scope; //Store class scope into a variable named $this

      //Iterate through the properties of the object
      for ( var i in properties )
      {

      (function(i)
      {
      // Dynamically create an accessor method
      $this[ "get" + i ] = function()
      {
      return properties[i];
      };
      })(i);
      }
      };

      this.getMutatorMethods = function(properties)
      {
      var obj = {}; //Object that will store private methods

      //Iterate through the properties of the object
      for ( var i in properties )
      {

      (function(i)
      {
      //Dynamically create a mutation method that parses for an integer and
      //Ensures it is positive.
      obj[ "set" + i ] = function(val)
      {
      if(isNaN(val))
      {
      properties[i] = val;
      }
      else
      {
      properties[i] = Math.abs(val);
      }
      };
      })(i);
      }

      return obj;
      };

      }

      //The WageWorker “subclass” inherits the properties and methods of Worker.
      WageWorker.prototype = new Worker();

      //Expects the following properties: wage, hoursPerWeek, weeksPerYear
      function WageWorker(properties)
      {

      //By assigning methods to the variable, we keep the mutator methods private to the class
      var wageWorker = this.getMutatorMethods(properties);

      //Make a property of the wageWorker object an object itself that holds class-specific properties
      wageWorker.employment = {EmploymentStatus: “hired”, CriminalRecord: “spotless”};

      this.getAccessorMethods(properties, this);
      this.getAccessorMethods(wageWorker.employment, this);

      //Functions a “boss” would have. Private to the class
      wageWorker.theBoss = this.getMutatorMethods(wageWorker.employment);

      //Calculates income
      this.getIncome = function()
      {
      return properties.Wage * properties.HoursPerWeek * properties.WeeksPerYear;
      }

      //Private method invocations that will override default values
      wageWorker.setWage(20);
      wageWorker.setName(“Tim”);

      //Fire the worker!
      wageWorker.theBoss.setEmploymentStatus(“fired!!!”);
      }

      var worker = new WageWorker(
      {
      Name: “Bob”,
      Wage: 10,
      HoursPerWeek: 40,
      WeeksPerYear: 48
      });

      alert(worker.getIncome()); //Outputs 38400 (20*40*48).
      alert(worker.getName()); //Outputs “Tim”
      alert(worker.getCriminalRecord()); //Outputs “Spotless”
      alert(worker.getEmploymentStatus()); //Outputs “fired!!!”
      worker.setEmploymentStatus(“Hired again…”); //ERROR: worker.setEmploymentStatus is not a function.

      0
  • david

    Saturday, October 2nd, 2010 21:57

    10

    The dynamically Generated Accessor methods example is nice but it lacks one thing to make the class act consistently.

    What if you create a new student as follows:

    noAge = new Student(
    {
    Name: “Bob”,
    Gender: “male”
    }
    );

    This means the getAge method will not be generated.
    A way to generate all the methods that are a part of the design is to add a defaults object.

    function Student( properties )
    {
    var $this = this, //Store class scope into a variable named $this
    defaults = {Name: ‘Nobody’, Age: 0, Gender: ‘undefined’};

    //Iterate through the properties of the object
    for ( var i in defaults )
    {

    (function(i)
    {
    // Dynamically create an accessor method
    $this[ "get" + i ] = function()
    {
    return properties[i] != undefined ? properties[i] : defaults[i];
    };
    })(i);
    }
    }

    Now the noAge student will have a getAge method.

    0
    • Joseph McCullough

      Monday, October 4th, 2010 09:11

      13

      David, that’s brilliant! I’ll get that incorporated into the article as soon as possible.

      0
  • Dave

    Thursday, September 30th, 2010 13:29

    6

    Thx Joseph, really didatic samples.

    0
  • Julian

    Thursday, September 30th, 2010 00:11

    5

    Excelent post!!, please give us more.

    0
  • luglio7

    Saturday, October 2nd, 2010 15:26

    9

    i don’t understand the syntax
    (function(i)
    {
    // something
    })(i)

    what’s the meaning of “(i)” ?

    0
    • Joseph McCullough

      Monday, October 4th, 2010 09:09

      12

      Hey luglio,
      That right there is a self executing function with i as a parameter for that function. The reason why we have to use the self executing function in this context is because closures only provide the last value of the variable within the parent function. Without the self executing function, only the last property would have its dynamic methods generated. Try it for yourself! Take out the self executing part and observe the results.

      0
    • david

      Sunday, October 3rd, 2010 15:29

      11

      ()(i); is a self executing function. This prevents you from adding a method that is only called on object construction.

      function Student( properties )
      {
      var $this = this, //Store class scope into a variable named $this
      defaults = {Name: ‘Nobody’, Age: 0, Gender: ‘undefined’};

      this.build_accessor = function(i)
      {
      // Dynamically create an accessor method
      $this[ "get" + i ] = function()
      {
      return properties[i] != undefined ? properties[i] : defaults[i];
      };
      };

      //Iterate through the properties of the object
      for ( var i in defaults )
      {
      this.build_accessor(i);
      }
      };

      Creating and executing a function at the same time is one of the nice javascript features.

      0
  • Jacob Orange

    Wednesday, October 13th, 2010 22:39

    15

    Thanks, this is really helpful. As a side note, what plugin do you use to get your code to appear as it does? It’s extremely clean!

    0
  • Brett Widmann

    Wednesday, January 26th, 2011 20:12

    17

    This has a lot of great tips! Thank you for the help.

    0
  • Node.js tutorials

    Wednesday, June 8th, 2011 08:43

    18

    It is too funny to say, i have saved this page for three times. When i have came to visit this from google. Very detail tutorial for newbie.

    0
  • Julian

    Monday, October 25th, 2010 09:23

    16

    Some good stuff, but confusing for those new to js oo when it comes to the section:
    CommissionWorker.prototype = new Worker();
    WageWorker.prototype = new Worker();

    Even if it’s not the time to delve into the details of how .prototype works – a brief explanation of how it is that this can come before the corresponding function statements would be nice. Does it have to come beforehand or is the order irrelevant?

    0
  • AKLP

    Wednesday, September 29th, 2010 15:12

    2

    This one of the really few detailed and “awesome” guides i saw in 1stwebdesigner, thanks!

    -1
    • Joseph McCullough

      Wednesday, September 29th, 2010 16:36

      3

      Thank you! I’d love to see how you apply it. Feel free to email me a link to your next JavaScript project so I can see how you use the Object Oriented Principles.

      0
  • Aneslin

    Thursday, September 30th, 2010 22:21

    7

    Awesome tutorial, and thanks for the great useful comments with other JS tutorial links.

    -1
  • Jonern

    Wednesday, September 29th, 2010 13:08

    1

    Great article! Nicely simplified and easy to understand… thanks!

    -1
    • Joseph McCullough

      Wednesday, September 29th, 2010 16:37

      4

      Glad to hear! Do you have any JavaScript projects that you could simplify using these principles?

      0
  • Node.js tutorials

    Wednesday, June 8th, 2011 08:43

    18

    It is too funny to say, i have saved this page for three times. When i have came to visit this from google. Very detail tutorial for newbie.

    0
  • Brett Widmann

    Wednesday, January 26th, 2011 20:12

    17

    This has a lot of great tips! Thank you for the help.

    0
  • Julian

    Monday, October 25th, 2010 09:23

    16

    Some good stuff, but confusing for those new to js oo when it comes to the section:
    CommissionWorker.prototype = new Worker();
    WageWorker.prototype = new Worker();

    Even if it’s not the time to delve into the details of how .prototype works – a brief explanation of how it is that this can come before the corresponding function statements would be nice. Does it have to come beforehand or is the order irrelevant?

    0
  • Jacob Orange

    Wednesday, October 13th, 2010 22:39

    15

    Thanks, this is really helpful. As a side note, what plugin do you use to get your code to appear as it does? It’s extremely clean!

    0
  • david

    Saturday, October 2nd, 2010 21:57

    10

    The dynamically Generated Accessor methods example is nice but it lacks one thing to make the class act consistently.

    What if you create a new student as follows:

    noAge = new Student(
    {
    Name: “Bob”,
    Gender: “male”
    }
    );

    This means the getAge method will not be generated.
    A way to generate all the methods that are a part of the design is to add a defaults object.

    function Student( properties )
    {
    var $this = this, //Store class scope into a variable named $this
    defaults = {Name: ‘Nobody’, Age: 0, Gender: ‘undefined’};

    //Iterate through the properties of the object
    for ( var i in defaults )
    {

    (function(i)
    {
    // Dynamically create an accessor method
    $this[ "get" + i ] = function()
    {
    return properties[i] != undefined ? properties[i] : defaults[i];
    };
    })(i);
    }
    }

    Now the noAge student will have a getAge method.

    0
    • Joseph McCullough

      Monday, October 4th, 2010 09:11

      13

      David, that’s brilliant! I’ll get that incorporated into the article as soon as possible.

      0
  • luglio7

    Saturday, October 2nd, 2010 15:26

    9

    i don’t understand the syntax
    (function(i)
    {
    // something
    })(i)

    what’s the meaning of “(i)” ?

    0
    • david

      Sunday, October 3rd, 2010 15:29

      11

      ()(i); is a self executing function. This prevents you from adding a method that is only called on object construction.

      function Student( properties )
      {
      var $this = this, //Store class scope into a variable named $this
      defaults = {Name: ‘Nobody’, Age: 0, Gender: ‘undefined’};

      this.build_accessor = function(i)
      {
      // Dynamically create an accessor method
      $this[ "get" + i ] = function()
      {
      return properties[i] != undefined ? properties[i] : defaults[i];
      };
      };

      //Iterate through the properties of the object
      for ( var i in defaults )
      {
      this.build_accessor(i);
      }
      };

      Creating and executing a function at the same time is one of the nice javascript features.

      0
    • Joseph McCullough

      Monday, October 4th, 2010 09:09

      12

      Hey luglio,
      That right there is a self executing function with i as a parameter for that function. The reason why we have to use the self executing function in this context is because closures only provide the last value of the variable within the parent function. Without the self executing function, only the last property would have its dynamic methods generated. Try it for yourself! Take out the self executing part and observe the results.

      0
  • Aldian

    Friday, October 1st, 2010 17:18

    8

    If my prototypical public methods need to access private attribute then I need to create the get/set mutator for that attribute. By creating getters and setters then I open the way for outside code to change my private attributes.
    Is there a way to enforce that only my prototypical public methods accessible from the outside world, but not my mutators?

    +1
    • Joseph McCullough

      Monday, October 4th, 2010 10:28

      14

      Yup, there sure is! Take this as a starting point, feel free to tweak as you see fit. Also, you can email me at joseph@vertstudios.com if you have any more questions!

      function Worker()
      {
      this.getAccessorMethods = function(properties, scope)
      {
      var $this = scope; //Store class scope into a variable named $this

      //Iterate through the properties of the object
      for ( var i in properties )
      {

      (function(i)
      {
      // Dynamically create an accessor method
      $this[ "get" + i ] = function()
      {
      return properties[i];
      };
      })(i);
      }
      };

      this.getMutatorMethods = function(properties)
      {
      var obj = {}; //Object that will store private methods

      //Iterate through the properties of the object
      for ( var i in properties )
      {

      (function(i)
      {
      //Dynamically create a mutation method that parses for an integer and
      //Ensures it is positive.
      obj[ "set" + i ] = function(val)
      {
      if(isNaN(val))
      {
      properties[i] = val;
      }
      else
      {
      properties[i] = Math.abs(val);
      }
      };
      })(i);
      }

      return obj;
      };

      }

      //The WageWorker “subclass” inherits the properties and methods of Worker.
      WageWorker.prototype = new Worker();

      //Expects the following properties: wage, hoursPerWeek, weeksPerYear
      function WageWorker(properties)
      {

      //By assigning methods to the variable, we keep the mutator methods private to the class
      var wageWorker = this.getMutatorMethods(properties);

      //Make a property of the wageWorker object an object itself that holds class-specific properties
      wageWorker.employment = {EmploymentStatus: “hired”, CriminalRecord: “spotless”};

      this.getAccessorMethods(properties, this);
      this.getAccessorMethods(wageWorker.employment, this);

      //Functions a “boss” would have. Private to the class
      wageWorker.theBoss = this.getMutatorMethods(wageWorker.employment);

      //Calculates income
      this.getIncome = function()
      {
      return properties.Wage * properties.HoursPerWeek * properties.WeeksPerYear;
      }

      //Private method invocations that will override default values
      wageWorker.setWage(20);
      wageWorker.setName(“Tim”);

      //Fire the worker!
      wageWorker.theBoss.setEmploymentStatus(“fired!!!”);
      }

      var worker = new WageWorker(
      {
      Name: “Bob”,
      Wage: 10,
      HoursPerWeek: 40,
      WeeksPerYear: 48
      });

      alert(worker.getIncome()); //Outputs 38400 (20*40*48).
      alert(worker.getName()); //Outputs “Tim”
      alert(worker.getCriminalRecord()); //Outputs “Spotless”
      alert(worker.getEmploymentStatus()); //Outputs “fired!!!”
      worker.setEmploymentStatus(“Hired again…”); //ERROR: worker.setEmploymentStatus is not a function.

      0
  • Aneslin

    Thursday, September 30th, 2010 22:21

    7

    Awesome tutorial, and thanks for the great useful comments with other JS tutorial links.

    -1
  • Dave

    Thursday, September 30th, 2010 13:29

    6

    Thx Joseph, really didatic samples.

    0
  • Julian

    Thursday, September 30th, 2010 00:11

    5

    Excelent post!!, please give us more.

    0
  • AKLP

    Wednesday, September 29th, 2010 15:12

    2

    This one of the really few detailed and “awesome” guides i saw in 1stwebdesigner, thanks!

    -1
    • Joseph McCullough

      Wednesday, September 29th, 2010 16:36

      3

      Thank you! I’d love to see how you apply it. Feel free to email me a link to your next JavaScript project so I can see how you use the Object Oriented Principles.

      0
  • Jonern

    Wednesday, September 29th, 2010 13:08

    1

    Great article! Nicely simplified and easy to understand… thanks!

    -1
    • Joseph McCullough

      Wednesday, September 29th, 2010 16:37

      4

      Glad to hear! Do you have any JavaScript projects that you could simplify using these principles?

      0

Comments are closed.

184.73.72.163 - unknown - unknown - US