Tuesday, 26 February, 2019 UTC


Summary

In this article, I would like to explain some tricky concepts in JavaScript that can get really confusing, depending on where you are in your development journey. Namely, I’ll discuss object references, scopes, context and instantiation in JavaScript. It should help you understand some behaviors that can otherwise seem odd with JavaScript.
First, an example to illustrate the point:
[] === [] // false 
Woah, what just happened an empty array is not equal to an empty array. JavaScript, how confusing can you be!

🐊 Alligator.io recommends:

ES6 for Everyone → A video course to learn modern JavaScript
ⓘ About this affiliate link
Object Reference
The concept of object reference can be very tricky, here for example let’s do a check to see if object1 and object2 is the same:
let object1 = { value:10 }; let object2 = object1; let object3 = { value: 10}; 
object1 === object2 //true 
We get true because both object1 and object2 are both pointing to the same reference data that’s in memory. If we check to see if object1 and object3 is the same:
object1 === object3 // false 
Interesting! they both have the same value but why are they not the same. That’s because object3 creates another reference in the memory, which isn’t the same as object1 so JavaScript treats both objects as being different.
To explain further, imagine object1 being created as an address in memory, then object2 pointing to object1 at the same address. While object3 is another address in memory. object1 address can never be the same as object3 address.
Array Reference
Back to the initial example of:
[] === [] // false 
In Javascript array’s are really objects behind the scene so JavaScript treats the first [] as a new object and store the reference in memory, then stores the second [] as a different reference in memory, So when checking for equality, it turns out they can’t be the same.
Scopes and Context
Context are always confused with scopes. A scope is always created when curly brackets are encountered. If we create a function, for example, a new scope is created:
function sampleScope() { let a = 'a'; console.log(a); } 
If we were to reference the variable a from outside the sampleScope function it wouldn’t be recognized because the variable is defined inside the sampleScope function scope.

Context

A context is different from scope, it tells you the current object we are currently referencing. Context is accessed using the this keyword. For example, if we log the current context we are in from the console in the browser with the following:
console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …} 
It tells us we are currently in the window objects. The this is a special keyword of Javascript that point’s to the current object or context:
this.alert('hello'); window.alert('hello); 
The two lines above are essentially the same thing because the this keyword references the window object because that’s the current context.
If we create a new object like so:
const object4 = { a: function() { console.log(this); } } object4.a(); // {a: ƒ} 
We see that it logs out the current context which is the object4 context.
Instantiation
Let’s say we want to keep track of the students we had in a classroom by having their names and gender, so we model out a class that looks like this:
class Student { constructor(name, gender){ console.log(this); this.name = name; this.gender = gender; } introduceStudent() { console.log(`${this.name}, ${this.gender}`); } } 
We have a class that we created accepts a name and a gender and also has access to a function that logs the student’s name.
Now let’s say we want to create a class representative without having to copy the same code and adding extra information, we can extend the Student class while creating a new class for the class representative, like so:
class Rep extends Student{ constructor(name, gender){ super(name, gender); } introduceClassRep() { console.log(`${this.name}, ${this.gender}, and I'm a class rep`); } } 
The extends keyword tells JavaScript to add whatever property the class extends from to the current class. Whenever we extend a class, we also need to call it’s constructor method, super gives us the power to do just that.
Now let’s create instances of both class:
const student1 = new Student('jane', 'female'); const student2 = new Rep('cole', 'male'); 
After creating these new instances you’ll see that the two console outputs are different. That’s simply because they are instances of different classes.
Conclusion
With JavaScript the behavior of objects can seem quite complicated at first, but understanding the underlining concepts can give you a lot of power and reveal the underlining simplicity.
We’ve looked at how object references, context, scope and instances come to play in JavaScript, and we’ve shown how to use them. Hopefully you now have a better understanding of these more advanced concepts! 🏋