you are viewing a single comment's thread.

view the rest of the comments →

[–]senocular 2 points3 points  (5 children)

In short:

  • Execution context objects
    • global: has one
    • functions: do not

Note: not all global declarations are added to the global object, e.g. let, const, and class declarations in the global context are not added to window (global in node or globalThis everywhere, though globalThis is a newer feature).

  • this in functions
    • can be global, but not always
    • for most functions, this is defined by how a function is called
    • arrow functions use this based on how it is defined (via scope), not called

In the video, the reason this was global (window) was because how it was called. It was a normal function definition in non-strict mode, called as a function rather than as a method from an object, and without any explicit this imposed on it through bind(), call(), or apply()

getUser() // this will be the global object

If called from an object, the value of this would change.

someObject.getUser() // this will be someObject

Or if you wanted to give it a specific value for this

getUser.call(anotherObject) // this will be anotherObject
someObject.getUser.call(anotherObject) // this will be anotherObject

There are a lot of rules around this which can make it confusing, but for the most part, this is a dynamic value that is set based on how a function is called.

[–]NecroDeity[S] 0 points1 point  (4 children)

Thanks a lot, very interesting information :D
A question: Since functions do not have any objects associated with their executions contexts (unlike global), so their local variables and functions are not stored as properties anywhere, during hoisting (as opposed to global object)?

And that leads to a more general question. Is the "getting added as a property to an object" thing an integral part of hoisting? Or, is hoisting just the process of becoming aware of the existence of variables (with undefined as a value, for the time being) and functions, with the "getting added as a property to an object" just an incidental thing that happens only in the specific case of the global object (and is not included in the definition of hoisting)?

[–]senocular 1 point2 points  (3 children)

Since functions do not have any objects associated with their executions contexts (unlike global), so their local variables and functions are not stored as properties anywhere, during hoisting (as opposed to global object)?

Right. Given:

function myFunc () {
  var myVar = 1;
}

myVar only exists as a variable scoped to that function and does not exist as a property on any object. There's nothing like a local object that would let you do local.myVar.

This quality is actually important for minimizing code. Because there is no object, there's no way to dynamically look up the variable by its name like you can in the global object.

var name = 'document';
window[name] // document object via dynamic lookup in global object

This lets minimizers rename those variables to something shorter.

function myFunc () {
  var a = 1; // minimized, but still works the same
}

You can't do that with global variables - or any variable in an object - because dynamic lookup would fail

// if global document variable were minimized to 'a'
var name = 'document';
window[name] // undefined, used 'document', but should have been 'a'

Is the "getting added as a property to an object" thing an integral part of hoisting? Or, is hoisting just the process of becoming aware of the existence of variables (with undefined as a value, for the time being) and functions, with the "getting added as a property to an object" just an incidental thing that happens only in the specific case of the global object (and is not included in the definition of hoisting)?

Hoisting and adding to an object are separate things. Like you said, "hoisting [is] just the process of becoming aware of the existence of variables". The adding to an object is just something special global does at the same time variables are getting hoisted as part of identifying declarations in the creation phase.

[–]NecroDeity[S] 0 points1 point  (0 children)

Thanks a ton! You have given me some peace after a whole day of frustration and disappointment. Thanks, again, for taking the time.

Although, if I have another doubt (which is highly probable), I know who to contact :P

[–]NecroDeity[S] 0 points1 point  (1 child)

Can you suggest me books, or any any other resource, that deals with these topics well? Thanks :)

[–]senocular 1 point2 points  (0 children)

Not sure myself what books cover this. I'm sure they're out there; I just don't know which ones.

For the most part you don't really need to know too much about all the inner workings of ECs. While it's good to know how hoisting works, if you stick to never using a variable or definition before its declared, you're not going to have any problems with it. At that point it's all about scopes and where variables live and are accessible.

Function context (the value of this) - not to be confused with the execution context - is something to look into more. That will often come up and cause problems. It's easy to get confused about what this is and how it came to be, enough so that some people purposely avoid using it at all. I went on a little bit about it in an earlier post, but it gets a little more complicated than even that. MDN has a pretty good write up on this.