- The tools
- The implementations
- The bad practices
Most of the tools we use in a Visual Studio environment are geared to languages targeting the CLR. If you program in C# or Visual Basic, you'll be assisted by Intellisense, class browsers, class diagrams, code snippets, code analysis, and a world class debugger. The menus will list refactoring commands, and unit testing is only a few keystrokes away.
If you want to write an application that will reach as many users as possible, then you'll be writing a web application. You can reach users on Windows, Macintosh, Linux, and hundreds of other platforms on devices both large and small.
Let's rewrite our first example using the  operator.
The above piece of script produces the same result as our first script. It creates a new object, then adds x and y properties to the object, then writes out the values. Note that if we access a property that does not exist, we'll get back a value of "undefined". For instance, the line of code "alert(p.z);" would force a dialog box to appear with the string "undefined" inside.
Creating Object Methods
We can also add functions into the collection of values inside an object. Functions associated with an object become methods of the object. The following code sample shows how to create and use a method with the name of "print".
Notice we alternate use of the . operator and the  operator. We can use these two operators interchangeably, for the most part, to create and access an object's properties and methods. Sometimes these operators lead to confusion, because it's not clear if a particular piece of code is trying to create new properties on an object, or if it's trying to set existing properties to new values. Fortunately, there is a third syntax available that makes our intent explicitly clear.
Object Literals and JSON
This is useful information for constructing objects, but it's only a starting point. To get to the next level of abstraction, we'll need to add a second piece of knowledge:
#2 is what we will discuss in the next topic.
The above code defines a function named "add". The function expects two parameters, and expects that these two parameters will both have x and y properties that it can add together. It returns the result as a new object (created in object notation) with x and y properties. We could use invoke this function as in the following sample:
The resulting dialog box will display "2,2".
Technically, what we've done with the add function is create a new function object, and assigned the function object to a variable named add. We could take the same function object and assign it to different variables and invoke the function through those variables.
The resulting dialog box should now display "3,3".
Functions as Methods
We can also assign a function object to an object property. As we noted before, this promotes the function to the status of "method".
What is a problem is that we have two "point" objects, but one has an add method and one does not. Remember, we are not defining classes like we would in C# or VB, we are simply creating objects and adding properties and methods on the fly. If we wanted to same add method in both point1 and point2, we could write the following code.
Fortunately, there is a better solution.
Constructor functions are just regular functions. It's just we've designed the function to be used with the new operator. By convention, we generally capitalize constructor functions to make other programmers aware of their significance.
When we use the new operator with the Point function, the new operator will first create a new object. The new operator then invokes the Point function and passes a reference to the newly created object in the implicit "this" parameter. Inside the Point function we are creating new name/value pairs using the parameter values passed to the function.
Constructor Functions and Object Methods
We can also create methods on an object inside a constructor function.
This approach works well, but there is an alternate approach we can use which is more in favor today. To understand this approach, we'll need to introduce a new piece of knowledge. Let's review the first two:
Now for number 3:
Let's talk about prototypes.
Remember that every function is an object, and every object references a prototype object. That means every constructor function references a prototype object. This is extremely useful when used in conjunction with the "new" operator, because of steps taken by the new operator:
- Create an empty object.
- Assign the value of the constructor function's prototype property to the new object's prototype property.
- Invoke the constructor function, passing the new object as the "this" reference.
The above 3 steps mean that all objects created by a constructor function will have the same prototype – the prototype object for the constructor function. If we can modify the constructor function's prototype object, we will modify all objects the constructor function ever creates (or has already created). You can almost think of every object as inheriting from it's prototype, because it will include all the properties and methods defined by its prototype. I say "almost" because this thinking can be dangerous in some edge cases.
Fortunately, there is an easy syntax we can use to add new properties and methods into a prototype object.
Putting It All Together
Let's re-write our sample once more, this time providing public "get" and "set" accesors for our points.
Client code can no longer access the x and y values of a point object directly. Instead, the code has to go through the set_ and get_ methods.
There is just one problem.
This is ok, because we can "simulate" namespace using objects. Let's put our "Point class" into a Geometry namespace.
This article presented three key pieces of knowledge:
This article is by K. Scott Allen. Questions? Comments? Bring them to my blog.