SlightlyLoony
Tera Contributor

find_real_file.pngThe light bulb just went off for our super-genius at right — finally, it all makes sense to him. What makes sense, you ask? Why, code like this (which I used in my last post😞


gr = this._get_real_gr(gr);


_get_real_gr() is a function, so why can't I just call it? Why is that pesky, awkward this. there in front of it?

Understanding the this keyword is critical to understanding how to work with JavaScript objects, so this is worth your time and attention to understand. Guzzle some coffee, pinch yourself, sedate the kids, muzzle the dog, just do whatever it takes to get yourself focused on understanding this for the next few minutes.

Try modifying the MACResolver script include from my last post to remove the this. in the two places where it prefixes the function call. Then try running it — you'll get this error in the log:

Evaluator: org.mozilla.javascript.EcmaError: "_get_real_gr" is not defined.
Caused by error in Script Include: 'MACResolver' at line 30

27:
28: // if we have a NIC here, get the real CI...
29: if (klass == 'cmdb_ci_network_adapter') {
==> 30: gr = _get_real_gr(gr);
31: if (!gr)
32: continue;
33:


But if you look at the source from my last post, you can see that function being defined. What's wrong with this moronic JavaScript compiler, telling you it's undefined when it's right there?

This is happening because without the this. JavaScript is expecting our function to be global, and it's not. Instead, our function is defined as a property in our MACResolver object. The this. prefix tells JavaScript to look for the function definition in this object. But what is this object? Well, that's different each time you create and use an object. Consider the test code from the last post:

var mac = new MACResolver();
var gr = mac.resolve('00:50:56:ae:33:d9');
gs.log(gr.sys_class_name + ': ' + gr.name);


In this code, we created a new instance of the MACResolver class and stored it in the mac variable. In the case of this example, the this. refers to the mac variable, and it is exactly as if you had written mac._get_real_gr(). But inside the object, in its own code, you're writing code that has to run no matter how the class is used. That's what the this. keyword does for you: it lets you invoke an instance function (aka a method) or refer to an instance variable (aka a property or a field) from within the object, no matter how it is being used.

Here's another reason why the this keyword is necessary. Imagine that in your code you already had a global function named _get_real_gr(). If it weren't for the this keyword, you'd have a confusing situation: an instance function and a global function with the same name. Which one should JavaScript actually invoke? The this keyword solves the problem: leave it off, and you're calling the global function. Put it in, and you're calling the instance function.

There now, that wasn't so hard, was it? Was it?

1 Comment