Object declarations with the {}
are a shorthand syntax that hides the object prototype:
let obj = {}; // what you wrote
let obj = new Object() // what your JS interpreter sees
obj.prototype.object // what your JS interpreter creates
This is very similar to using the class
shorthand syntax. But class
is a double abstraction, hiding the fact it is really creating a function and that it's doing so with the function prototype:
// what you wrote
class test{
constructor(x){
this.x = x;
}
}
// what your JS interpreter creates
test.prototype.constructor
So when you are logging obj
and you get [object Object]
, your JS interpreter is telling you that you have created an object of prototype Object. You're confusing yourself with test
, just stop with that - they are in different scopes and don't mean the same thing. Learn prototypes first.
JS Under the Hood
The thing to remember is that Javascript is an object-oriented language but does not use class-based inheritance like most other OOP. Javascript uses prototype inheritance. When you instantiate a class in JS, it's not really a class in the classical programming sense.
Just to reiterate, your JS class
actually gets defined as a function. Try it out:
console.log(typeof test) //output: function
There's more to it though. Let's say we extend your example a bit further with another method:
class test{
constructor(x){
this.x = x;
}
// Custom method
outputX() {
console.log(this.x)
}
}
What have we actually done? As mentioned above, the JS interpreter will read your class and leverage the function prototype to create it. So what makes this different than just defining a function?
Because you used class
, the function prototype automatically assigns a constructor method to your new test
prototype. All other custom methods - like outputX
that I added in - get added onto the test
prototype.
// All valid
test.prototype.constructor
test.prototype.outputX
test.prototype.whateverMethodYouMake