Prototype vs. Class (*)

devfish·2023년 1월 13일
0

Javascript

목록 보기
19/30

Let's dive deeper into how javascript 'class' objects really function under the hood. There are many quirks in the js language in its creation and handling of objects, and especially if you're used to a different language that was strongly 'object oriented' (like me), this can get very, very confusing. There are some clever methods that have become standard js design patterns to mimick how OOP languages function, but there are some key differences in its inherent mechanism worth highlighting that separate it from the classic OOP paradigm - they're worth looking into not only for avoiding mistakes, but also leveraging its strengths into better and best practices.

How the Class Constructor in JS Really Works

Here is the new ES6 'class' constructor in action..
You can see how I tried creating a changeLastName() method inside the class, but that method were not created at all in the instantiated objects of that class, so when I tried to access that function through it, I ran into a TypeError. To create new methods that would propagate to the instantiated objects, I had to add prototype - Employee.prototype.changeLastName. Only then was I able to create a method that could be invoked with instances of that class.

The strange thing is that my first attempt did indeed create a method within the class, which I was then able to invoke via the class name. It did not change the properties of all its instance objects though.. what it did actually, was create a separate property within that class that were not inherited by its instance objects.

So what is happening here!? Well this demonstrates how the 'class' object is not really a 'class' in the classic sense. It is an object like any other, that also functions as a constructor. It can have separate properties/methods of its own like any object.

'Class' definition in js encapsulates these two things: constructor, and prototype.

Whenever you define a function, it gets an automatically created property called prototype. The prototype property points to a special "prototype" object, which is also automatically created with each function. It is THAT object that contains all the shared "members" for your "class." (link)

Takeaway:

In other languages a class is a single thing, but "class" definitions in JavaScript are split into TWO PARTS:
1. The constructor (a plain old function), such as Employee
2. The prototype, an automatically created object that every function gets.
So a "class" is actually TWO separate objects! (link)

  • For an illuminating visual guide to JS's constructor/prototype pattern, check out this link.
  • Following this experiment here and trying it out yourself is also a great way to explore how this works.

Prototypes vs. Classes in a Nutshell

Changes made to the class itself does not propagate! You need to change the 'prototype' object to do that.

In more "sane" object-oriented languages, you create a class, you spawn objects off of them, and you're done with it. If you need to make a global change you do it at the class level, and all instantiated objects pick up that change automatically. But JavaScript is NOT a "sane" object-oriented language. ~Steve Kwan

Prototypes are object instances, not types.

The key takeaway is that prototypes don’t define a type; they are themselves instances and they’re mutable at runtime, with all that implies and entails. ~Justen Robertson

https://www.toptal.com/javascript/es6-class-chaos-keeps-js-developer-up

For a deep dive into this topic, check out As a JS Developer, This Is What Keeps Me Up at Night. The developer is of the opinion that ES6 with its 'class' designation just muddied the waters with "syntactic obscurantism. It tries to hide the prototypical inheritance model and the clumsy idioms that come with it, and it implies that JavaScript is doing something that it is not." Pop Quiz from the seasoned full-stack developer:

Instance vs. Prototype Object Methods

When a method you're invoking does not exist in the instantiated object itself, the engine will search for it in its prototype object and invoke it if it exists. But if you create a method that shares the same name in the instantiated object itself, that method will henceforth become the one that is invoked, until it is deleted.
https://www.toptal.com/javascript/es6-class-chaos-keeps-js-developer-upimg source

Constructor vs. Prototype Methods

When you define constructor methods, it is copied for every instance of that class whereas for prototype methods, the instances just 'reference' its prototype object method. Changing prototype properties would change it for every instance of that class/prototype.

Prototype Pattern Advantages

Some advantages of using prototypal inheritance includes that it minimizes memory usage!

Static Class Methods

As we observed above, it is possible to create class methods that belong to the class object itself, as opposed to the prototype. These are called static methods - they refer to methods that can be called directly from the class, that do not need instantiation of the class. (You cannot call a static method by the instance object, but only through the class object itself.) To access non-static methods, however, you need an instance object of that class.

static methods belong and operate on the class (object) level, so should be reserved to define functions for that class as a whole. You can use the static keyword to differentiate it from prototype methods.

Here a class method is used to compare two instance objects:

References

An exploration of JavaScript's prototype and constructor properties

Constructors considered mildly confusing

Javascript Constructor/Prototype Patterns

Deep Dive: Understanding Constructor and Prototype

__

Use of prototype vs. class methods

Deep Dive: ES6 CLass Chaos Keeps JS Developer Up

profile
la, di, lah

0개의 댓글