Getting Good with JavaScript - Andrew Burgess [19]
With all that said, let's get back to new. The classes in other languages use constructor functions to construct the new objects. In JavaScript, constructors are regular functions, written to create new object and called with the keyword new in front of them. Let's take a look at how to write and call this type of function.
Let's say we want to create truck objects. I know: this isn't necessarily practical. You probably won't ever need truck objects in JavaScript, but it's something you'll be familiar with while we discuss new and it's crew.
So, here's a function that will create a truck:
Example 4.3
function Truck(model) {
this.num_of_tires = 4;
this.kilometers = 0;
this.model = model;
}
var my_truck = new Truck("Hercules");
console.log(my_truck);
Notice two things here: first, we're defining all these variables as properties of the object this. Second, we don't return anything from this function. Both of these are because we plan to call this function with the new keyword. At the end there, you can see how we call this function.
Take note of how we use new here. This does two things to the function. First, it changes this to a new clean object. Obviously, we then add our custom properties within the function. The second thing new does is assure that this is returned. Now the value of my_truck is just the same as if we had done this:
Example 4.4
var my_truck = {
num_of_tires : 4,
kilometers : 0,
model : "Hercules"
};
console.log(my_truck);
That's the idea of using new: we get a super easy way to create objects. Obviously, you won't use this when you just need one or two simple objects. It's most useful when you have a lot of functionality to pack into an object, or you want to create a lot of similar objects.
We'll come back to new a bit later. For now, let's discuss the other ways to change this.
call and apply
I mentioned earlier that everything in JavaScript is an object—even functions. Since functions are objects, they can have properties and methods. call and apply are two methods that functions have by default.
The only reason for these functions to exist is to change the value of this within the function. Let's see how to do it.
Example 4.5
function Truck (model, num_of_tires) {
this.num_of_tires = num_of_tires;
this.kilometers = 0;
this.model = model;
}
var basic_vehicle = { year : 2011 };
Truck.call(basic_vehicle, "Speedio", 4);
console.log(basic_vehicle);
Here, we're calling the Truck function via it's call method. The first parameter of call is the object we want to be considered this within the function. Since we're not using new with this call to Truck, it doesn't create a new object or return this by default. That's what we want in this case, because we're modifying an existing object.
ROCKSTAR TIP
An aside on primitive vs. reference values: You might think that, although we're modifying an existing object, we will lose those changes unless we assign them to a new variable, or back to basic_vehicle. That would be the case if our variable was a primitive value. However, objects (and arrays) are reference values: values passed by reference. A primitive value (such as a string or number) is stored in a spot in your computer's RAM, and we keep track of it with a variable. When we pass that variable to a function, we copy that value to a new spot in memory, point the parameter name to that spot, and work with that inside the function, so that the original is unharmed. It's different with reference values: when we pass an object or array to a function, the parameter points to the very same spot in memory as the original variable. This means that the this inside Truck.call(basic_vehicle) is the very same basic_object we have outside the function.