JavaScript Constructors

Share on Facebook1Share on Reddit0Tweet about this on Twitter3Share on Google+0

Because syntax and control structures look very similar in classic OOP languages (Java, C#) to JavaScript, it can be easy for experienced developers to jump-in, make progress, and then shoot themselves in the foot due to misunderstanding core differences in underlying language design.

One of those core differences is how functions can function as objects with constructors.

In a classic OOP language, a class,  constructor, and usage might look something like this:

Although the syntax is similar, doing something like this in JavaScript will land you in a bad place:

Scope

The first and most pressing issue is scope management.  Look back up the the JavaScript example — The function used in place of a class, is just that: a Function. Whereas a custom class is a datatype, a template for data, our function is a function in the same way as this is a function:

Primarily, the problem is with the scope of the this keyword with in functions.  Inside of a OOP language class, the this keyword refers to the parent object — the class that it is inside of. For example:

However, in side of a JavaScript function, the this keyword refers to the global scope, or the window object. Thus:

For the uninitiated, this can cause big problems. For example, consider:

A function/object Building, which contains the properties height, location, and occupancy, which are assigned like this: this.location = “123 N. 789 W.” Since the this keyword refers to the window object, your function has just overwritten window.location, the property used in changing the current location (url) of the page. Whoops!

But wait, there is a solution!

It is true, that a JavaScript object/function is really just a function — but you can create new instances of the function using the new keyword. Not only does the new keyword created a new instance (so you can have multiple objects of the same type on a page), but also assigns the scope of the this keyword to the function, NOT the window object. So, to use the previous example without clobbering the global scope:

However, if you have ever written a line of jQuery, you might be shaking your head in disagreement. Like you, I write something like this weekly:

So, how does that work?

To make sure that jQuery object is allways called with the new keyword, it does it for you, every time. See the jQuery source constructor:

So, each time $(“#asdf”) is used, jQuery returns a new jQuery.fn.init object. Now, keep in mind that this is one of several hundred lines within jQuery’s constructor source, but the key section for this subject. We can implement this method, with a few checks, in our code very easily.

Conclusion and template

So, to avoid clobbering the global scope, and to be convenient for implementers of your code, here is a well functioning JavaScript constructor template that can be implemented in your code:

See a demonstration of new keyword usage

JS Bin

Share on Facebook1Share on Reddit0Tweet about this on Twitter3Share on Google+0
  • pp

    You wrote this incorrect bit of javascript two times:

    this.function bark(){ // *this* refers to window object

    • mdjasper

      Thanks for the correction. All behold the danger of Copy&Paste!

  • btlachance

    Small typo: you’re forgetting to pass along the given arguments (name, age) in your “return new Dog();” line.

    • mdjasper

      Thanks for the correction. I have fixed the post.

  • Bob Foster

    In the two examples that use it, where does ‘message’ come from?

    • mdjasper


      function Dog(){
      //...
      this.bark = function(){{ // *this* refers to window object
      return message;
      }
      }

      Thanks for the question. The message, in “return message;” is an example of the interior of the function. It is not really related to the purpose of the code but is there for illustration. I suppose “message” is declared in the comment section “//…”

  • Barnus

    Nice explanation, cheers for posting

  • Pingback: Convirtiendote.Pro Como crear una libreria en JavaScript()