This.name vs name


#1



https://www.codecademy.com/en/courses/objects-ii/3/1?curriculum_id=506324b3a7dffd00020bf661#

When I create the sayName method, why do I have to use this.name instead of name? When we created the Class we state this.name = name;

Thanks for your time!

// create your Animal class here

function Animal(name, numLegs) {
    this.name = name;
    this.numLegs = numLegs;
}

// create the sayName method for Animal

    Animal.prototype.sayName = function() {
        console.log("Hi my name is " + this.name)
    }


#2

this is a built in object associated with function which refers to the owner object context. In a constructor, it is the current instance that is being created.

We pass in the values we wish the new instance to have for the own properties as formal parameters, name, and numLegs. They are then assigned to the new instance object.

    this.name = name;
    this.numLegs = numLegs;

When we invoke the constructor,

var dog = new Animal('Rex', 4);

The this object is assigned to dog.

console.log(dog.name);     // Rex
console.log(dog.numLegs);  // 4

Inside a method, this refers to the execution context, which in this case will be dog.

dog.sayName();    // Rex

If our method referred to only name it would be searched for in global scope and might be something like the window name, but it won't be Rex.


#3

If our method referred to only name it would be searched for in global scope

@mtf Does this mean it would search for name in the global scope and only in that scope?

I ask because I am one of those people @gaurangtandon referred to who omitted this in a similar exercise; I mean I understand why I should use this, but not yet completely why I have to use this.

I was wondering why if the method can't find anything called name in the current scope it wouldn't expand to the next scope and so forth in order, and/or if it couldn't recognize the key name as a variable name.

I know that wouldn't be an ideal/efficient way for it to run, but I was curious why it doesn't at least work in some messed up kind of way (but not necessarily as intended and assuming no global name variables, which I presume would then be used**) instead of throwing a reference error.

I'm sorry if I'm digressing too much from the OP's question; when I saw your reply I thought it might be the answer to mine, too.


**I tried declaring a global variable and it didn't print anything in the class console, but did print the global variable in a different web console.


Bleep Bleep: Variable is to Global Variable as This.Key is to...?
#4

No, not only. If the function is nested in multiple scopes, they will all be searched for name, right up to the top of the scope chain. If not found in a parent scope, name will be found in the global scope since window has a name property (that we cannot change).

global scope
window.name
function() {
    var name;
    function() {
        var name;    << finds this one
        function() {
            console.log(name);
        }
    }
}

`
Will continue reading your question, and edit in more answers, as they arise.


#5

Where the next scope is above the current one. JS never searches down the scope chain; only up.

With respect to instance variables, they not only have scope, but execution context which is associated to the this object. Whenever we wish to refer to an instance variable, we need to refer to it in object context, this.name so that the interpreter finds the own property, name of the current object.

bob.name

is an identifierName, whereas, name is an identifier. The interpreter will never jump out of scope to search for an indentifierName. If not found in the context of the object, it will throw a reference error.

A final aside, with respect to name. The window object has a built in property, name that is reserved for system use. It is used by JS to denote the window name. We cannot change it and accessing it may return nothing, or it may return a name for the current window.

We cannot make an assignment to this variable in window scope. Only in function (or object) scope. For this reason, the variable should always be declared in a function, never left as a global (no var).


#6

Thank you for your help, @mtf. I have been studying your answers for the past few days.

Where the next scope is above the current one. JS never searches down the scope chain; only up.

Am I understanding correctly that down means (nested) further to the right and up closer to the left? If so, I am confused about this part:

The interpreter will never jump out of scope to search for an indentifierName

In program:

blob = {
    blobette: "Hello",
    sayHello: function() {
        console.log(this.blobette);
    }

I can understand why the interpreter wouldn't search for the identifier (if I don't supply identifierName context), but here is it not jumping up to the next scope and, thanks to identifierName, locating blobette?

Or am I looking at this the wrong way and this means the program didn't search because I provided identifierName?

And in that case, if the method was actually console.log(blob) is this also not searching for identifierName because in this case blob is the Object name and not acting as an identifierName?

If not found in the context of the object, it will throw a reference error.

I understand what this means, but how does it work in conjunction with:

If not found in a parent scope, name will be found in the global scope since window has a name property (that we cannot change).

Do I still get the reference error because I didn't set the window.name property to anything? Or will the method throw a reference error for each object it's nested in?

A final aside, with respect to name.

Thank you so much for including this aside! Now I understand why we can use name in these later exercises but not earlier ones (where they would have been set as global vars). I'd read that we could use "illegal" names for keys but didn't completely realize what that meant until now.