
ES6 Classes: Class Syntax – Prototypes in Disguise
ES6 Classes: Class Syntax – Prototypes in Disguise 관련
Okay, we've wrestled with constructor functions and call()
and Object.create()
to get inheritance working with prototypes. It's powerful, but let's be honest, it can feel a little verbose and indirect, especially if you're used to class-based languages.
That's where ES6 classes come to the rescue. They offer a much more streamlined and class-like syntax for creating object blueprints in JavaScript.
Let's rewrite our PersonConstructor
example using the class
syntax. Get ready for a breath of fresh air.
PersonClass
- Constructor Function Reimagined as a Class
Here's how we can define our Person
blueprint as a class:
class PersonClass {
// Using the 'class' keyword!
constructor(name, age) {
// 'constructor' method - like our old constructor function
this.name = name; // Still using 'this' in the constructor
this.age = age;
}
greet() {
console.log(`Hello, I'm ${this.name}`);
}
}
Doesn't that look much cleaner and more organized? Let's break down the class syntax:
class PersonClass { ... }
: We start with theclass
keyword, followed by the class name (PersonClass
in this case). Class names are conventionally capitalized.constructor(name, age) { ... }
: Inside the class, we have a special method calledconstructor
. This is like our oldPersonConstructor
function. It's where we put the code to initialize the properties of a newPersonClass
object when it's created withnew
. We still usethis
inside theconstructor
to refer to the new object being created.greet() { ... }
: This is how we define methods in a class. We simply write the method name (greet
), followed by parentheses for parameters (none in this case), and then the method body in curly braces. Notice that we don't use thefunction
keyword here. It's justgreet() { ... }
.
Creating Objects from a Class - Still Using new
To create objects from our PersonClass
blueprint, we still use the new
keyword, just like we did with constructor functions:
const classPerson1 = new PersonClass("Charlie", 28);
const classPerson2 = new PersonClass("Diana", 32);
console.log(classPerson1.name); // Output: Charlie
classPerson1.greet(); // Output: Hello, I'm Charlie
Yep, it works exactly the same way as our constructor function example, but the class syntax is just much more readable and less cluttered.
DeveloperPersonClass
- Inheritance Made Easy with extends
Now, let's tackle inheritance using classes. Remember how we had to use call()
and Object.create()
to get DeveloperPersonConstructor
to inherit from PersonConstructor
? With classes, inheritance becomes super straightforward using the extends
keyword.
Here's how we can rewrite DeveloperPersonConstructor
as a DeveloperPersonClass
that inherits from PersonClass
:
class DeveloperPersonClass extends PersonClass {
// 'extends' for inheritance!
constructor(name, age, programmingLanguage) {
super(name, age); // 'super()' calls the parent class constructor!
this.programmingLanguage = programmingLanguage;
}
code() {
// Developer-specific method
console.log(`${this.name} is coding in ${this.programmingLanguage}`);
}
}
Look at that. Inheritance in classes is declared using the extends
keyword: class DeveloperPersonClass extends PersonClass {...}
. This line alone says, "Hey JavaScript, DeveloperPersonClass
should inherit from PersonClass
."
Inside the DeveloperPersonClass
constructor, we have this line: super(name, age);
. super()
is crucial for class inheritance. It's how we call the constructor of the parent class (PersonClass
in this case). When we call super(name, age)
, it's essentially doing the same thing as PersonConstructor.call(this, name, age)
in our constructor function example—it's running the PersonClass
constructor to set up the inherited properties (name
and age
) on the DeveloperPersonClass
object.
After calling super()
, we can then add any developer-specific properties or methods to our DeveloperPersonClass
, like this.programmingLanguage = programmingLanguage;
and the code()
method.
Using DeveloperPersonClass
- Inheritance in Action, Cleaner Syntax
Let's create a DeveloperPersonClass
object and see inheritance in action with this cleaner syntax:
const classDevPerson1 = new DeveloperPersonClass("Eve", 35, "JavaScript");
console.log(classDevPerson1.name);
//
// Eve (Inherited from PersonClass!)
console.log(classDevPerson1.age);
//
// 35 (Inherited from PersonClass!)
classDevPerson1.greet();
//
// Hello, I'm Eve (Inherited from PersonClass!)
console.log(classDevPerson1.programmingLanguage);
//
// JavaScript (Developer-specific)
classDevPerson1.code();
//
// Eve is coding in JavaScript (Developer-specific)
It works exactly as expected. classDevPerson1
inherits name
, age
, and greet()
from PersonClass
and also has its own programmingLanguage
and code()
methods. But the class syntax makes the inheritance relationship much more obvious and easier to work with.
Classes: Syntactic Sugar, Prototype Power Underneath
Let's be crystal clear again: JavaScript classes are syntactic sugar over prototypes. They are a more user-friendly way to write code that is still based on prototypes and constructor functions behind the scenes.
When you define a class, JavaScript is actually doing these things for you under the hood:
- It's creating a constructor function (like our
PersonConstructor
). - It's setting up the
.prototype
property of that constructor function. - When you use
extends
, it's usingObject.create()
andcall() to
set up the prototype chain for inheritance.
Classes don't change the fundamental prototype-based nature of JavaScript OOP. They just give us a more familiar and less verbose syntax to work with it.
So, Are Classes Just "Fake" Classes?
Some people argue that JavaScript classes are “fake” because they’re merely syntactic sugar. But honestly, that’s not the point at all. Syntactic sugar is awesome—it makes our code easier to read, write, and maintain. For those coming from a class-based language background, classes make object-oriented programming in JavaScript much more approachable and understandable.
The key takeaway is that while classes give you a neat, familiar syntax, you still need to understand the underlying mechanism: prototypes. Classes are just a friendly layer on top of JavaScript’s prototype system.