Scope and context may seem similar, but they actually have very different functions
At first glance, computer code looks like an esoteric combination of keystrokes that go on for hundreds or even thousands of lines without much organization or cohesion. In reality, code is a highly organized and hierarchical system where processes are synchronized but separated.
One possible reason for this confusion is because scope and context both refer to when variables or certain keywords become relevant, and what exactly they refer to when they’re called upon. Let’s take a closer look at scope first.
In the most simplified of terms, scope has two levels: global scope and local scope. Global scope refers to variables that are accessible anywhere because they are declared outside of any individual functions or methods — usually at the top of the file. They exist in the global space, ready to be called upon at any time. The first example below concerns global scope.
Local scope refers to variables that are accessible within the boundaries of their function. In this example, we have our initial declaration of the variable
dog at the top of our file, which is assigned to the string of “goodBoy.” Immediately below, we console.log the
As expected, this first
console.log prints ‘goodBoy,’ as seen on the right side of the image. Then, we have a function of
showScopeExample(), which reassigns our
dog variable to the string of “badDog.”
This function is immediately invoked, but when we
console.log “dog” for the second time on line 10, it still prints as “goodBoy.” Even though the second
console.log occurs after we reassign the variable inside of the function, the
dog variable is not currently capable of returning as “badDog.” This is by design.
Our re-declaration of
dog inside of
showScopeExample() is locally scoped. The easiest way to know this is to look at its location. The re-declaration lies in between opening and closing curly brackets, which act as barriers to the relevancy of these variables.
In this example, all we’ve changed is the location of the second
console.log, which is now inside the boundaries of the
showScopeExample() function. As seen in the console to the right, the first
console.log still prints “goodBoy” as expected.
Unfortunately, our second
console.log now prints “badDog” when we invoke
showScopeExample() (poor pup). This is because our second
console.log is now held within the boundaries of the curly brackets, and it will print information that is located within the same scope.
Finally, the third
console.log returns to printing “goodBoy.” This is again because it does not have access to the local reassignment and resorts to the initial declaration.
this. The value of
this depends on where it is being invoked.
this in the global space will return the entire window object. This is because the window object is the starting point of all the code we write. Give it a try, and you’ll likely get something like this in response…
The endless white text we get in return is the
window object. The first rule of
this is that by default, it refers to the window object. If you ever get the chance, you should explore the window object returned from invoking
this in the global context.
But what happens if we invoke
this somewhere other than the global context? If we invoke
this in the context of a new object, it will return that object, just as it returned the entire window object. Let’s look at a simple example and then build on it.
In the example above, we’ve created a new object which we’ve named
newContextObj. When we invoke the method
invokeThisInNewContext() it returns the entire
This is the same as when it returned the window object in our first example. The only difference is that the window object is a very large and complex object, and our
newContextObj is very small and simple. The second rule of
this is that when it is invoked in the context of an object,
this will refer to that object.
Finally, the third rule of
For example, we could have a class that produces instances of a
car object. Despite the fact that the cars all have sizes, capacity, and engine types, these three things probably differ from car to car. Below is an example of
this being invoked in the context of an instance of
What we see in the example above is the invocation of the
whereIsThis() method on our instance of
ContextObj. In this third and final example, the keyword
this refers to this specific instance of
ContextObj, no matter how many instances of
ContextObj exist in our code.
These three examples attempt to summarize
this in its most basic forms, and you’ll find in your own experiences that this becomes a very handy tool to have at your disposal. The best way to become more familiar with concepts such as context and scope is simply experimenting with them.
Open your preferred text editor and start creating functions and object of your own. Mess around with variable placement in your functions. When do you have access to them and when do they return undefined?
Create increasingly complex objects and invoke this in increasingly specific and limited contexts. There is no better way to become comfortable coding than by getting your fingers on the keyboard and struggling through concepts, one at a time.