Friday, July 23, 2010

A primer on class variables and methods in JavaScript

I figured this was a great topic for the beginning of this blog, because up until I was introduced to jQuery I had no idea that classes ever existed in JavaScript. Before I took up serious web development, my JS experience was limited to copying cheesy scripts from JavaScript Source into whatever awful personal website I'd be building at the time in high school. However, you can actually use functions (as jQuery does) to create classes in JavaScript that will make your code immediately more extensible and organized. The variables and methods within those classes can have various levels of access (public, private, static and privileged), and I'll go over public and private today using classes from my Sprites and Animations post as examples.

JavaScript Classes

This here is how you create a new class:

  1. // Class declaration
  2. function Sprite(x, y, w, h, startAnimation) {
  3.   // Do constructor stuff here, instantiate local variables, etc.
  4. }
  5. // Create a Sprite object
  6. var mySprite = new Sprite(200, 200, 16, 16, "DefaultAnimation");

Easy enough. However, how you declare variables and methods within your class will determine where you can access them. We'll start with public variables/methods, as they're the most open.

Public Variables/Methods

Public variables and methods are accessible by any class in your code. Let's add a public variable and draw() method for the Sprite class.

  1. function Sprite(x, y, w, h, startAnimation) {
  2.   // Do constructor stuff here, instantiate local variables, etc.
  3. }
  4. // Public variable
  5. Sprite.prototype.currentAnimation = null;
  6. // Public method
  7. Sprite.prototype.draw = function() {
  8.   // Do drawing related things here
  9. }
  10. // Create a Sprite object and use it
  11. var mySprite = new Sprite(200, 200, 16, 16, "DefaultAnimation");
  12. mySprite.currentAnimation = "MyAnimation";
  13. mySprite.draw();

You might be wondering what "prototype" is all about. Consider it to be the main copy of your class. Every object that you create from your class will contain the variables/methods you define under its prototype. Also, note that Sprite.prototype.draw is assigned in the same manner as a variable is, except that you're assigning a function to it. Since currentAnimation and draw() are public, you are able to access them directly from outside of your object. While this wide-open behavior ensures that you'll have access to them whenever the need arises, it's always advisable to only make member variables/functions as accessible as they need to be! That's where privacy comes in.

Private Variables/Methods

Private variables and methods are not visible outside of the class they belong to, and can only be accessed from the outside via the class' public methods. If we add a private variable to the Sprite class, it can't be accessed simply by mySprite.privateVar - rather, you would have to create a public function to retrieve its value as seen below.

  1. function Sprite(x, y, w, h, startAnimation) {
  2.   // Private variable
  3.   var currentAnimation = startAnimation;
  4.   // Private function (specify new active animation)
  5.   var setAnimation = function(animationName) {
  6.     this.currentAnimation = animationName;
  7.   }
  8. }
  9. // Public function to access private variable/method
  10. Sprite.prototype.publicSetAnimation = function(animationName) {
  11.   this.currentAnimation = animationName; // OK
  12.   // OR
  13.   this.setAnimation(animationName); // OK
  14. }
  15. // Create a Sprite object and use it
  16. var mySprite = new Sprite(200, 200, 16, 16, "DefaultAnimation");
  17. mySprite.currentAnimation = "MyAnimation"; // FAIL
  18. mySprite.setAnimation("MyAnimation"); // FAIL
  19. mySprite.publicSetAnimation("MyAnimation"); // OK

This example is a bit tricky, but bear with me. The Sprite class now has a private variable currentAnimation, and a private method called setAnimation that changes its value. Both are unavailable at the bottom of the code snippet where we create a Sprite object and attempt to access them directly. However, the public method publicSetAnimation is a "gateway" of sorts that can be used to change the variable through either method.

Summary

  • Public variables and methods are visible to all classes.
  • Private variables and methods are only visible to the class they belong to.

The decision to use public or private variables and methods will vary depending on the specific situation. As a rule of thumb, ask yourself "do I really need to be able to access this from outside directly?" If you find yourself answering yes, you should still consider keeping it variable private and providing a public method via which to set/retrieve its value. This strategy is also helpful in case you have to alter the method by which a variable is set/retrieved, as it's (hopefully) likely you'll only have to make the change once to your public method. Happy... classing I guess!

Next up: I will cover static and protected variables/methods in a future post, followed by something other than level creation. I'm starting to think it would be a good idea to get my character moving around a test "room", and possibly figuring out the physics situation before I delve into creating the levels themselves. Always be willing to reevaluate your plan! :-)

1 comment:

  1. The variables and methods within those classes can have various levels of access (public, private, static and privileged), and I'll go over public and private today using classes from my Sprites and Animations post as examples.psd to css

    ReplyDelete