Simple "this" keyword works weirdly in Javascript.
First of all we need to understand that what ever code you write will be in Execution context.
Functions create execution context.
Excecution contexts are created in call-statck.
"this" always refers to object in execution context.
Top most object is global object in node or window object in browser.
All codes below is based on window object.
Var is the only statement attached to global/window object, not let and const.
Console logging not inside any function

What if it is inside function?

So both points to global/window object.
Let's declare a variable and access it!

Within the function,

Note:"this" always point to object
We will create an object!

What if another "var a" is declared?

So this always refers to contained object.
Here the contained object is "obj".
Also, by default , "this" takes global/window object.(previous examples) if no container object is available.
What if object method is stored in another variable?

It gives you undefined,weird , right?
Let's declare another "var a" outside obj!

Oh my god, it gives us the "var a" declared outside obj.
So the next rule is
It is not where it is declared but where it is called! - call site
Here x is called from global object - call site object is global object even though obj.method is assigned to x.
So,
obj.method --> container object is obj.
x --> container obj is global/window object.
Always remember where the call site and its associated call site.
How to add obj's "this" to x?
Use call method from Function prototype and the pass the object we want to have as a container.

Call vs. Apply vs. Bind
All methods (call,apply and bind) belong to Functions.
For simplicity, I use the different code for illustration.

So call method passes the this reference object to the function.
If obj1 is used,this points to obj1 and same explanation obj2.
What if there are parameters to functions other than "this reference" object?

We can add as many parameters as possible except for the first one(this referer).
What about apply method?
Same as call but parameters are passed as arrays.

What about bind method?
Same as call, but it is not immediately returns or invoked.Hence we can store to some variable.

Note:I used return in the printName
The "new" keyword:
Remember why we have learned call/apply/bind in first place.
Yes, because we can't store an object to another variable at the calling site because "this referer" changes.
What did we do?
We create a variable and store the object.
Then bind the "this refer object" to the new variable.
Then we invoke the function later.That's why we use 'bind'.
What if all the things are automated by one single word? Welcome to "new"!
"new" creates brand new object inside the function automatically.
When the function is called using "new," it is called constructor function.
"this" is binded automatically with newly created object.
Constructor function automatically returns created object with key-value we added.

The "new" keyword is the basis of Javascript classes.
TL;DR:
1)Depends on call-site
2)Which object is container?
3)Called with call/apply/bind
4)new keyword that automates object creation,binding and returning object.