This forum is now read-only. Please use our new forums! Go to forums
4/30 Wondering why we need to use the this keyword to specify job?
Hello I got my code to run and display but only after I added the this keyword as placeholder object in front of property job inside object james:
console.log("Hi, I work as a " + this.job);
My understanding is that the this keyword is a useful placeholder to allow multiple, different objects to access the same properties or methods— however, I’m wondering why was it necessary to use it in this case inside a single object – why couldn’t I just access the value of jobs for james by simply saying job considering the fact that I’m inside the object brackets and therefore I’d assume the properties would have scope to be referenced by merely their name…
Just curious of whether there’s something I overlooked in my understanding of the this pointer. Any brief explanations would be very much appreciated! Thanks :)
Answer 545d803452f8639e31001006
This may come up in later lessons. Notice that we have written the method inside the object literal:
var james = {
job: "programmer",
married: false,
sayJob: function() {
console.log("Hi, I work as a " + this.job);
}
};
In the above, sayJob
is dedicated to the james
object. But what if we have other objects that similarly have a job
property? Do we write (or clone) this same method in those objects? Answer: no. We define the function outside the object where any object can reference it. Consider three objects,
var james = {
job: "programmer",
married: false
}
var mary = {
job: "typesetter",
married: false
}
var bob = {
job: "designer",
married: true
}
var sayJob = function(){
console.log("Hi, I work as a " + this.job);
};
james.sayJob = sayJob;
mary.sayJob = sayJob;
bob.sayJob = sayJob;
Now all of these are owners of their respective sayJob()
instance. There is only one function, not one for each. this
is what makes it possible to have multiple owners. They only really own their instances, not the function itself.
james.sayJob(); // Hi, I work as a programmer
mary.sayJob(); // Hi, I work as a typesetter
bob.sayJob(); // Hi, I work as a designer
The upcoming units that cover object constructors and prototypes will further enlighten you in respect to this
.
Answer 547e454e631fe94635000894
I see you understand how this
keyword works in Javascript, so here’s the real answer to your question, as to why it’s best practice to use this
:
You are absolutely correct that you could easily do:
var james = {
job: "programmer",
married: false,
sayJob: function() {
console.log("Hi, I work as a " + james.job);
}
};
But what if you were to go back and rewrite your code and you changed var james
to var john
?
var john = {
job: "programmer",
married: false,
sayJob: function() {
console.log("Hi, I work as a " + james.job);
}
};
You’ll get an error that james is undefined, or similar. If you keep this
, you have fewer lines of code to maintain.
4 comments
It makes perfect sense to me why this.job is better than james.job, for no other reason than you might later change the name of the object. But why doens’t a simple [job] work? Why do you need to be any more specific than that, if the function is already restricted to this particular object instance, regardless of what it’s called?
[job] is not a variable, objectName[‘job’] and objectName.job are. job
is an identifier outside of object scope. In object scope, james.job
is an identifierName. ‘identifier => attribute`.
Got it! You’re right, I was approaching it as if [job] were a var. But it’s not. There is NO scenario in all of JS were you can reference an object property, whether inside or outside an instance, without including the name of the instance itself. I just needed to be smacked out of that train of thought. Thanks!
Try this in the console: job = “Programmer” [Enter] window.job [Enter] this.job [Enter]. Window is the instanced object when in global scope. There is still object reference, except the root doesn’t need object scope on its variables, so identifier === identifierName. In EVERY other case, as you have mentioned, the instance is paramount (else we could end up with something that has been defined globally getting into the fray)
Answer 545d798c7c82ca3eca0011fc
All objects in JS are instances. The owner is given by the reference, or identifier. When we access properties inside a function, this
is the identifier currently in scope of the function. Eg.
james.sayjob = function(){
console.log("Hi, I work as a " + this.job);
};
james
is the owner, the object in function scope. this.job
is actually james.job
.
Answer 545daf99631fe9afa7001449
I understand how this
works, I’ve already completed the track although I’m sure this will be useful to others mulling over how the this pointer works. My question was, given my understanding of this
and as you’ve reiterated here, if the this
pointer is meant to be used as a placeholder for multiple objects, why would it be necessary inside a singular object literal like object james – no other object is inheriting the sayJob function in that case because it is defined ONLY in the james object. As you say, in this case, “sayJob is dedicated to the james object”. However, my code wouldn’t run without the this
pointer in front of job inside the sayJob function when running with just the single object james. I was wondering why it was necessary for me to do that. Still, FANTASTIC explanation. Thank you taking the time to post it.
1 comments
That’s not due to fault in your code, it’s due to the test runner the site uses to evaluate your code. Simply put, the test is expecting this.job, although james.job works too.
Answer 5524a73386f5528206000245
@Justin Chaloupka,
Here is the sample code from in my comment:
var a='global';
function foo(){
var a='local';
console.log(a, window.a, this.a);
}
//foo(); // local global global
obj = {
a: 'object'
};
obj.foo = foo;
obj.foo(); // local global object
In the lab: context vs scope
Answer 556a133193767614e500035b
console.log(“Hi, I work as a “ + james[‘job’]);
I used the literal constructor syntax and it worked fine…. although both object constructor and literal constructor would work fine I suppose, However it is best practice for what I have come to realise so far or better it is safer to use the “This” keyword ….this.job…..
1 comments
this can have any object context, james is just one object. The range of application is limited to it.
Answer 546aa128631fe97a2a00206c
It doesn’t /own/ the function, it only uses it as a sort of “snapshot”, and it just so happens that while the function is inside of the james object, it can only be used by james. If you were to say job it wouldn’t know where to direct the “snapshot”. That is my understanding of it explained with simplicity… Please let me know if I’m wrong. :D
3 comments
Owning a function is probably not the best terminology, but owning an instance of a method could be easily characterized in the snapshot analogy you’ve given, here. I wouldn’t say you are wrong any more than I would say that I am right. But if it gives us a clearer picture of what we’re dealing with, anything helps, imho.
When we think about it, all functions are owned by some object, going right back to global functions belonging to the ‘window’ object. alert() and window.alert() are the same function.
Wow… strange thing JavaScript is!
Answer 55654b87e0a300689200037e
Supplemental
Scope and Context
In JavaScript, the function
has a very special role. It is an object, which we can see in the prototype chain, but it has a constructor (other than Object), meaning a function is actually a class. We know what that means. Its prototype is packed full of goodies. One of them,this
, the context variable, is in scope with everything in the function body, including the parameters as given in the other nifty property,arguments
.
Given these properties, and the nature of scope, we can see how nesting functions creates many levels of scope. Any variable declared with var
in any function immediately identifies with the scope of that function.
The tricky thing to see at first is how the scope chain works. When we reference a variable, JavaScript first looks in the scope where the reference is made for that variable. This is why var a in a function trumps var a outside of it. But what if a
doesn’t exist in the current scope? JS goes looking up the scope chain to the next level. If it is found there, then that’s what gets used.
We can have a function in a function in a function in a function, and still JS will find an a
at some level, or throw an error. ReferenceError: ‘a’ is not defined, or some such message.
That’s what scope is more or less about. Where is the variable declared? Where we use it, or where we define it is not a factor in determining scope. Only where it is declared. Consider this expression:
var a;
(function(){
(function(){
(function(){
(function(){
(function(){
a = "Finally, I get defined";
})();
})();
})();
})();
})();
console.log(a);
This is some mighty powerful stuff, so we are on our best if we soak it all in. There are a dozen ways we can explore and demonstrate scope in this basic construct. I hope the reader does. And definitely read up on this, as if I need to press that point at this stage.
An object, no matter how it is constructed or what is in its prototype can only ever have one context, itself; I am. That’s my context. roy.birthday = "not saying; getting old"
. birthday
is in roy
context. It’s sort of like scope, but not the same thing. john.birthday = "John who?"
. Now we’re in john
context. Both object instances can have the same constructor, but they may also have completely different scope. It all depends upon where the instances were declared.
Oh what a tangled web we weave. Yes, it’s a blitheringly confusing subject but one we must tackle and get akin to. Separate the two and you have won. Confuse the two, and the battle is just begun.
4 comments
baby roy, you are the best and this clears up a lot of misconceptions i had. but can you please tell me why the code below works when it doesn’t print anything to the console? this happened in the section before, but I understood why my code was right in that section. In this section it seems like my code doesn’t make any sense in that adding “james.job=james.sayJob” somehow makes it correct according to codecademy.
var james = { job: “programmer”, married: false, sayJob: function() { console.log(“Hi, I work as a “ + this.job); } };
// james’ first job
james.sayJob(“Fry cook”);
// change james’ job to “super programmer” here james.job = james.sayJob
// james’ second job james.sayJob();
james.sayJob(), no argument. james.job = “super programmer”; james.sayJobj(); again, no argument. The method only reports the current property value for job. “programmer,” then, “super programmer.”
When we set a variable to receive a return value from a function, then we should be sure the function returns a value. A function that does something procedural often has no return value, such as is the case with jame.sayJob(). There is no defined return value, therefore the assignment to a variable will be undefined
.
When we assign a name reference only to a function that is already defined, that reference may invoke the function to which it refers. james.sayJob = sayJob is a name reference, only. To invoke this we will use james.sayJob().
Answer 55808107d3292ffbd700035b
I couldn’t have any answer when I post it. I don’t know why.
var jules = { job: “développeur”, fiance: false, disJob: function() { // completez cette methode console.log(“Salut, je travaille comme “ + this.job); } };
// premier job de jules jules.disJob();
// changez le job de jules pour mettre “super développeur” ici jules.job = “super développeur”;
// second job de jules jules.disJob();
Answer 55c506249113cb448500004f
I just passed 4/30 in the Français track with this code:
var jules = {
job: "développeur",
fiance: false,
disJob: function() {
// completez cette methode
console.log("Salut, je travaille comme " + this.job);
}
};
// premier job de jules
jules.disJob();
// changez le job de jules pour mettre "super développeur" ici
jules.job = "super développeur";
// second job de jules
jules.disJob();
Answer 55d2289d9113cb71bc00029f
Another way to look at it is say you have a variable number: 0;
inside some class and you have a method printNumber()
and it has a variable defined as number: 5;
within the method console.log(number)
which one will be printed? the variable within the method of course. Why? well because if you wanted to access the variable outside the method you would have done something like console.log(this.number)
or console.log(objectName.number)
. To sum it up the this
keyword becomes very useful along the lines of scoping and it’s even more useful when you’re utilizing class constructors where properties and methods can vary within each instance of the class that’s where this
can also refer to a particular instance of the class.
Popular free courses
- Free Course
Learn SQL
In this SQL course, you'll learn how to manage large datasets and analyze real data using the standard data management language.Beginner friendly,4 LessonsLanguage Fluency - Free Course
Learn JavaScript
Learn how to use JavaScript — a powerful and flexible programming language for adding website interactivity.Beginner friendly,11 LessonsLanguage Fluency - Free Course
Learn HTML
Start at the beginning by learning HTML basics — an important foundation for building and editing web pages.Beginner friendly,6 LessonsLanguage Fluency
28 comments
thanks for enlightening this fact i was getting confused too
Thanks, this clarifies a TON
beautifully explained. thanks!
very clear explanation. thanks a lot.
thanx it made the concept of this pointer crystal clear to me!
Awesome explanation, thanks
good work :)
I’m not sure this answers OP’s question for me. This is a great explanation as to why you should keep a function like this outside the scope of a single object instance. I get that. But my question is still…IF I’m including the function inside this particular instance (james), then why is [this.] needed at all? Why doesn’t just [job] work? If the scope of the function is restricted to this instance, then what else could [job] be referring to?
Again, I’m not saying that putting the function inside the james instance is the way to go. I honestly have no idea if it’s good practice. I assume this lesson instructs me to do it that way simply to make a point. But if I were to do it…why doesn’t a simple [job] work?
If you just use [job], it will be looking for a global variable (ie, a variable defined outside of the object). You need to use this.someVariable so the computer knows you’re talking about a property of the object, not a global variable.
Have a look at these two examples I just made. The first one is correct because the method references properties of the object, while the second is referencing global variables outside of the object.
Correct: http://jsfiddle.net/jalnt/9jzuwauo/1/
Wrong: http://jsfiddle.net/jalnt/9jzuwauo/2/
@tajom Your explanation together with the jsfiddle examples were super useful
Glad I could help :)
Thanks man, kept trying ‘this’ out of the object, kept giving me error..
@Roy Man you’re good at demonstrations…
what if you would use just +job instead of +this.job?
Then you would be referencing a global variable, not an instance variable.
job
is not defined, so will throw a reference error.instance.job
is defined within each object instance, andinstance
inside the function is ‘this’.@Roy – doesn’t “this” inside the function refer to the function itself and not the parent object? Would creating a “self” variable set to a passed instance of “this” be the actual solution? Ex.: sayJob: function( this ) { var self = this; console.log( “Hi, I work as a “ + self.job ); };
sayJob: function( this )
function is already inthis
context so no parameter needed.this
is the owner object, an instance perhaps of a Person class, or if not that, a plain object, the name of which is the owner object, and therefore , ‘this’. When things start getting complicated within a function, it is useful to clone ‘this’ as ‘self’, but in a basic scenario it is redundant and serves no purpose while leaking memory.this
is to context, asfunction
is to scope. A function written in global scope will have ‘window’ context. Consider.var a='global'; function foo(){var a='local'; console.log(a, window.a, this.a);} foo();
Output : local global global. Now add this code and comment the foo() call.obj = { a: 'object' }; obj.foo = foo; obj.foo();
Output: local global object@Roy: what do you mean by ‘window’ context? what does window.a mean?
The Window object is the context in which everything is housed. It is the top of the global scope chain.
what does window.a mean? When we declared
var a='global'
we essentially added a property to the Window object. That property is, window.a. This is good to know since what if we run into a function that has its own variable,a
and we for some reason need to access the globala
? Simple. Inside the function,a
is the locally scoped variable, andwindow.a
is the globally scoped one. We can still access it from inside a function that has a variable of the same name.Remember, variables are scoped to where they are declared, not where they are defined. That’s why scoping and variable declarations should always be planned ahead of time. What gets hoisted for permanent use, and what gets garbage collected. I barely see this through the fog, so don’t sweat it if these concepts are still a blur.
great explaination yet not working for me!
@Sam, here is where to post a new Question: https://www.codecademy.com/forums/objects-ii/0/exercises/3
@Roy thanks will do.
Hi, Roy, thanks.
This is a great explanation. I’m still unclear as to why you have to enter james.sayJob = sayJob; but hopefully I’ll get it moving forward
sayJob is a generic function written with a this variable to identify execution context. When we set a property of the same name on a defined object (such as ‘james’) to reference that function (not invoke it) then the object can invoke it on its own context.