Getting Good with JavaScript - Andrew Burgess [20]
After the object that will be this (you could call this the context of the function), we can pass in any parameters necessary. These will be passed to the function being executed. As you can see in our above example, the second parameter "Speedio" is being passed to Truck as its first parameter. The third parameter 6 becomes the second parameter of Truck. Of course, this will work for as many parameters as you required
There's an alternate form of call, named apply. The difference here is that apply takes only two parameters. The first is the context object. The second is an array of parameters that will be passed to the function. This is useful if you have the parameters as an array, instead of as loose variables. For example, let's say we ask the user to enter the model of the truck and the number of wheels it has into a textbox. The string user_input represents what we may have gotten back from them:
Example 4.6
function Truck (model, num_of_tires) {
this.num_of_tires = num_of_tires;
this.kilometers = 0;
this.model = model;
}
var basic_vehicle = { year : 2011 },
user_input = "Speedio 18";
Truck.apply(basic_vehicle, user_input.split(" "));
console.log(basic_vehicle);
This is a great place to use apply. We call split on that input string and split it on a single space character; this returns an array that would look like this: ["Speedio", "18"]. If we were going to use Truck.call here, we would cache that array in a variable and pass the its elements individually. like this:
var user_array = user_input.split(" ");
Truck.call(basic_vehicle, user_array[0], user_array[1]);
Obviously, this is more work; so we can just pass that array to apply, and it will assign the elements of the array to the parameters of the function we're applying it to in order.
If you're like me, and have a hard time remembering whether it's call or apply that takes the array, then notice that array and apply both start with a (and end with "y", and have a double consonant, if that's any help).
Inside an Object
Okay, there's one more way to change the value of this. We've talked about object literals enough that you're familiar with them. Well, remember that we can use functions as the value of a property—a method, it's usually called. Check this out:
var waitress = {
name : "Ashley",
greet: function (customer) {
customer = customer || " there!";
return "Hi" + customter + " My name is Ashley; what can I get you?";
}
};
Behold a waitress object; nothing too complicated is going on here; she's got a name and a greet function. However, what would happen if we ran this:
waitress.name = "Melissa";
That resets her name property; but she'll still be greeting people by calling herself Ashley! That won't do; but how can we reference the name property of the object?
It won't be obvious that we need to change that return message to this:
return "Hi" + customter + " My name is " + this.name + "; what can I get you?";
The million dollar question is, why do we do it that way? Let's step through what you're probably thinking. Your first thought might be to use name as a variable and just put it in there, but since it's a property, that doesn't work. Next, you might try this:
return "Hi" + customer + " My name is " + waitress.name + "; what can I get you?";
Yes, that works, but the problem here is that we could do this:
Example 4.7
var waitress = {
name : "Ashley",
greet: function (customer) {
customer = customer || " there!";
return "Hi" + customer + " My name is " + waitress.name + "; what can I get you?";
}
};
doppelganger = waitress;
waitress = null;
doppelganger.greet(); // failure!
Think about this code: remember that objects are a reference value. This means that when we create an object literal, it is stored in memory