{"id":391,"date":"2023-12-04T13:00:00","date_gmt":"2023-12-04T14:00:00","guid":{"rendered":"http:\/\/sobre-portugal.com\/?p=391"},"modified":"2024-06-12T20:25:07","modified_gmt":"2024-06-12T20:25:07","slug":"how-marketing-changed-oop-in-javascript","status":"publish","type":"post","link":"http:\/\/sobre-portugal.com\/index.php\/2023\/12\/04\/how-marketing-changed-oop-in-javascript\/","title":{"rendered":"How Marketing Changed OOP In JavaScript"},"content":{"rendered":"

How Marketing Changed OOP In JavaScript<\/title><\/p>\n<article>\n<header>\n<h1>How Marketing Changed OOP In JavaScript<\/h1>\n<address>Juan Diego Rodr\u00edguez<\/address>\n<p> 2023-12-04T14:00:00+00:00<br \/>\n 2024-06-12T20:05:40+00:00<br \/>\n <\/header>\n<p>Even though JavaScript\u2019s name was coined from the Java language, the two languages are worlds apart. JavaScript has more in common with <a href=\"https:\/\/en.wikipedia.org\/wiki\/Lisp_(programming_language)\">Lisp<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Scheme_(programming_language)\">Scheme<\/a>, sharing features such as first-class functions and lexical scoping.<\/p>\n<p>JavaScript also borrows its prototypal inheritance from the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Self_(programming_language)\">Self<\/a> language. This inheritance mechanism is perhaps what many — if not most — developers do not spend enough time to understand, mainly because it isn\u2019t a requirement to start working with JavaScript. That characteristic can be seen as either a design flaw or a stroke of genius. That said, JavaScript\u2019s prototypal nature was marketed and hidden behind a \u201cJava for the web\u201d mask. We\u2019ll elaborate more on that as we go on.<\/p>\n<p>JavaScript isn\u2019t confident in its own prototypal nature, so it gives developers the tools to approach the language without ever having to touch a prototype. This was an attempt to be easily understood by every developer, especially those coming from class-based languages, such as Java, and would later become one of JavaScript\u2019s biggest enemies for years to come: You don\u2019t have to understand how JavaScript works to code in JavaScript.<\/p>\n<h2 id=\"what-is-classical-object-oriented-programming\">What Is Classical Object-Oriented Programming?<\/h2>\n<p>Classical <strong>object-oriented programming (OOP)<\/strong> revolves around the concept of classes and instances and is widely used in languages like Java, C++, C#, and many others. A class is a blueprint or template for creating objects. It defines the structure and behavior of objects that belong to that class and encapsulates properties and methods. On the other hand, objects are instances of classes. When you create an object from a class, you\u2019re essentially creating a specific instance that inherits the structure and behavior defined in the class while also giving each object an individual state.<\/p>\n<p>OOP has many fundamental concepts, but we will focus on <strong>inheritance<\/strong>, a mechanism that allows one class to take on the properties and methods of another class. This facilitates code reuse and the creation of a hierarchy of classes.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/marketing-changed-oop-javascript\/classical-oop.jpg\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"450\" src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/marketing-changed-oop-javascript\/classical-oop.jpg\" alt=\"Diagram showing one class with two objects connected to another class connected to two more objects.\" \/><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Diagram showing one class with two objects connected to another class connected to two more objects. (<a href=\"https:\/\/files.smashing.media\/articles\/marketing-changed-oop-javascript\/classical-oop.jpg\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<div data-audience=\"non-subscriber\" data-remove=\"true\" class=\"feature-panel-container\">\n<aside class=\"feature-panel\">\n<div class=\"feature-panel-left-col\">\n<div class=\"feature-panel-description\">\n<p>Meet <strong><a data-instant href=\"\/printed-books\/image-optimization\/\">Image Optimization<\/a><\/strong>, Addy Osmani\u2019s new practical guide to optimizing and delivering <strong>high-quality images<\/strong> on the web. Everything in one single <strong>528-pages<\/strong> book.<\/p>\n<p><a data-instant href=\"https:\/\/www.smashingmagazine.com\/printed-books\/image-optimization\/\" class=\"btn btn--green btn--large\">Jump to table of contents \u21ac<\/a><\/div>\n<\/div>\n<div class=\"feature-panel-right-col\"><a data-instant href=\"https:\/\/www.smashingmagazine.com\/printed-books\/image-optimization\/\" class=\"feature-panel-image-link\"><\/p>\n<div class=\"feature-panel-image\">\n<img decoding=\"async\" loading=\"lazy\" class=\"feature-panel-image-img\" src=\"https:\/\/archive.smashing.media\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/87fd0cfa-692e-459c-b2f3-15209a1f6aa7\/image-optimization-shop-cover-opt.png\" alt=\"Feature Panel\" width=\"480\" height=\"697\" \/><\/p>\n<\/div>\n<p><\/a>\n<\/div>\n<\/aside>\n<\/div>\n<h2 id=\"what-s-prototypal-oop-in-javascript\">What\u2019s Prototypal OOP In JavaScript?<\/h2>\n<p>I will explain the concepts behind prototypal OOP in Javascript, but for an in-depth explanation of how prototypes work, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Inheritance_and_the_prototype_chain\">MDN has an excellent overview on the topic<\/a>.<\/p>\n<p>Prototypal OOP differs from classical OOP, which is based on classes and instances. In prototypal OOP, there are no classes, only objects, and they are created directly from other objects.<\/p>\n<p>If we create an object, it will have a built-in property called <code>prototype<\/code> that holds a reference to its \u201cparent\u201d object prototype so we can access its prototype\u2019s methods and properties. This is what allows us to access methods like <code>.sort()<\/code> or <code>.forEach()<\/code> from any array since each array inherits methods from the <code>Array.prototype<\/code> object.<\/p>\n<p>The prototype itself is an object, so the prototype will have its own prototype. This creates a chain of objects known as the <strong>prototype chain<\/strong>. When you access a property or method on an object, JavaScript will first look for it on the object itself. If it\u2019s not found, it will traverse up the prototype chain until it finds the property or reaches the top-level object. It will often end in <code>Object.prototype<\/code>, which has a <code>null<\/code> prototype, denoting the end of the chain.<\/p>\n<p>A crucial difference between classical and prototypal OOP is that we can\u2019t dynamically manipulate a class definition once an object is created. But with JavaScript prototypes, we can add, delete, or change methods and properties from the prototype, affecting the objects down the chain.<\/p>\n<blockquote><p>\u201cObjects inherit from objects. What could be more object-oriented than that?\u201d<\/p>\n<p>— <a href=\"https:\/\/crockford.com\/javascript\/prototypal.html#:~:text=supply%20the%20member.-,Objects%20inherit%20from%20objects.,them%20new%20fields%20and%20methods.\">Douglas Crockford<\/a><\/p><\/blockquote>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/marketing-changed-oop-javascript\/prototypal-oop.jpg\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"450\" src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/marketing-changed-oop-javascript\/prototypal-oop.jpg\" alt=\"Diagram showing the flow between two objects that are each connected to two other objects\" \/><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Diagram showing the flow between two objects that are each connected to two other objects. (<a href=\"https:\/\/files.smashing.media\/articles\/marketing-changed-oop-javascript\/prototypal-oop.jpg\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<h3 id=\"what-s-the-difference-in-javascript-spoiler-none\">What\u2019s The Difference In JavaScript? Spoiler: None<\/h3>\n<p>So, on paper, the difference is simple. In classical OOP, we instantiate objects from a class, and a class can inherit methods and properties from another class. In prototypal OOP, objects can inherit properties and methods from other objects through their prototype.<\/p>\n<p>However, in JavaScript, there is not a single difference beyond syntax. Can you spot the difference between the following two code excerpts?<\/p>\n<div class=\"break-out\">\n<pre><code class=\"language-javascript\">\/\/ With Classes\n\nclass Dog {\n constructor(name, color) {\n this.name = name;\n\n this.color = color;\n }\n\n bark() {\n return `I am a ${this.color} dog and my name is ${this.name}.`;\n }\n}\n\nconst myDog = new Dog(\"Charlie\", \"brown\");\n\nconsole.log(myDog.name); \/\/ Charlie\n\nconsole.log(myDog.bark()); \/\/ I am a brown dog and my name is Charlie.\n<\/code><\/pre>\n<\/div>\n<div class=\"break-out\">\n<pre><code class=\"language-javascript\">\/\/ With Prototypes\n\nfunction Dog(name, color) {\n this.name = name;\n\n this.color = color;\n}\n\nDog.prototype.bark = function () {\n return `I am a ${this.color} dog and my name is ${this.name}.`;\n};\n\nconst myDog = new Dog(\"Charlie\", \"brown\");\n\nconsole.log(myDog.name); \/\/ Charlie\n\nconsole.log(myDog.bark()); \/\/ I am a brown dog and my name is Charlie.\n<\/code><\/pre>\n<\/div>\n<p>There is no difference, and JavaScript will execute the same code, but the latter example is honest about what JavaScript is doing under the hood, while the former hides it behind syntactic sugar.<\/p>\n<p>Do I have a problem with the classical approach? Yes and no. An argument can be made that the classical syntax improves readability by having all the code related to the class inside a block scope. On the other hand, it\u2019s misleading and <strong>has led thousands of developers to believe that JavaScript has true classes when a class in JavaScript is no different from any other function object<\/strong>.<\/p>\n<blockquote class=\"pull-quote\">\n<p>\n <a class=\"pull-quote__link\" aria-label=\"Share on Twitter\" href=\"https:\/\/twitter.com\/share?text=%0aMy%20biggest%20issue%20isn%e2%80%99t%20pretending%20that%20true%20classes%20exist%20but%20rather%20that%20prototypes%20don%e2%80%99t.%0a&url=https:\/\/smashingmagazine.com%2f2023%2f12%2fmarketing-changed-oop-javascript%2f\"><\/p>\n<p>My biggest issue isn\u2019t pretending that true classes exist but rather that prototypes don\u2019t.<\/p>\n<p> <\/a>\n <\/p>\n<div class=\"pull-quote__quotation\">\n<div class=\"pull-quote__bg\">\n <span class=\"pull-quote__symbol\">\u201c<\/span><\/div>\n<\/p><\/div>\n<\/blockquote>\n<p>Consider the following code:<\/p>\n<div class=\"break-out\">\n<pre><code class=\"language-javascript\">class Dog {\n constructor(name, color) {\n this.name = name;\n\n this.color = color;\n }\n\n bark() {\n return `I am a ${this.color} dog and my name is ${this.name}.`;\n }\n}\n\nconst myDog = new Dog(\"Charlie\", \"brown\");\n\nDog.prototype.bark = function () {\n return \"I am really just another object with a prototype!\";\n};\n\nconsole.log(myDog.bark()); \/\/ I am really just another object with a prototype!\"\n<\/code><\/pre>\n<\/div>\n<p>Wait, did we just access the class prototype? Yes, because classes don\u2019t exist! They are merely functions returning an object (called constructor functions), and, inevitably, they have a prototype which means we can access its <code>.prototype<\/code> property.<\/p>\n<p>It almost looks like JavaScript tries to hide its prototypes. But why?<\/p>\n<h2 id=\"there-are-clues-in-javascript-s-history\">There Are Clues In JavaScript\u2019s History<\/h2>\n<p>In May 1995, <a href=\"https:\/\/thehistoryoftheweb.com\/postscript\/netscape-mosaic-coup\/\">Netscape<\/a> involved JavaScript creator <a href=\"https:\/\/en.wikipedia.org\/wiki\/Brendan_Eich\">Brendan Eich<\/a> in a project to implement a scripting language into the Netscape browser. The main idea was to implement the Scheme language into the browser due to its minimal approach. The plan changed when Netscape closed a deal with Sun Microsystems, creators of Java, to implement Java on the web. Soon enough, Brendan Eich and Sun Microsystems founder Bill Joy saw the need for a new language. A language that was approachable for people whose main focus wasn\u2019t only programming. A language both for a designer trying to make a website and for an experienced developer coming from Java.<\/p>\n<p>With this goal in mind, JavaScript was created in 10 days of intense work under the early name of <em>Mocha<\/em>. It would be changed to <em>LiveScript<\/em> to market it as a script executing \u201clive\u201d in the browser but in December 1995, it would ultimately be named <em>JavaScript<\/em> to be marketed along with Java. This deal with Sun Microsystems forced Brendan to accommodate his prototype-based language to Java. <a href=\"https:\/\/www.infoworld.com\/video\/89115\/javascript-creator-brendan-eich-on-the-genesis-of-the-popular-programming-language-true-technologis\">According to Brendan Eich<\/a>, JavaScript was treated as the \u201csidekick language to Java\u201d and was greatly underfunded in comparison with the Java team:<\/p>\n<blockquote><p>\u201cI was thinking the whole time, what should the language be like? Should it be easy to use? Might the syntax even be more like natural language? […] Well, I\u2019d like to do that, but my management said, \u201cMake it look like Java.\u201d<\/p><\/blockquote>\n<p>Eich\u2019s idea for JavaScript was to implement Scheme first-class functions — a feature that would allow callbacks for user events — and OOP based on prototypes from Self. He\u2019s <a href=\"https:\/\/brendaneich.com\/2008\/04\/popularity\/\">expressed this before<\/a> on his blog:<\/p>\n<blockquote><p>\u201cI\u2019m not proud, but I\u2019m happy that I chose Scheme-ish first-class functions and Self-ish prototypes as the main ingredients.\u201d<\/p><\/blockquote>\n<p>JavaScript\u2019s prototypal nature stayed but would specifically be obscured behind a Java facade. Prototypes likely remained in place because Eich implemented Self prototypes from the beginning and they later couldn\u2019t be changed, only hidden. We can find a mixed explanation <a href=\"https:\/\/brendaneich.com\/2011\/01\/harmony-of-my-dreams\/\">in an old comment on his blog<\/a>:<\/p>\n<blockquote><p>\u201cIt is ironic that JS could not have class in 1995 because it would have rivaled Java. It was constrained by both time and a sidekick role.\u201d<\/p><\/blockquote>\n<p>Either way, JavaScript became a prototype-based language and the most popular one by far.<\/p>\n<div class=\"partners__lead-place\"><\/div>\n<h2 id=\"if-only-javascript-embraced-its-prototypes\">If Only JavaScript Embraced Its Prototypes<\/h2>\n<p>In the rush between the creation of JavaScript and its mass adoption, there were several other questionable design decisions surrounding prototypes. In his book, <a href=\"https:\/\/www.amazon.com\/JavaScript-Good-Parts-Douglas-Crockford\/dp\/0596517742\"><em>JavaScript: The Good Parts<\/em><\/a>, Crockford explains the <em>bad<\/em> parts surrounding JavaScript, such as global variables and the misunderstanding around prototypes.<\/p>\n<p>As you may have noticed, this article is inspired by Crockford\u2019s book. Although I disagree with many of his opinions about JavaScript\u2019s bad parts, it\u2019s important to note the book was published in 2008 when ECMAScript 4 (ES4) was the stable version of JavaScript. Many years have passed since its publication, and JavaScript has significantly changed in that time. The following are features that I think could have been saved from the language if only JavaScript had embraced its prototypes.<\/p>\n<h3 id=\"the-this-value-in-different-contexts\">The <code>this<\/code> Value In Different Contexts<\/h3>\n<p>The <code>this<\/code> keyword is another one of the things JavaScript added to look like Java. In Java, and classical OOP in general, <code>this<\/code> refers to the current instance on which the method or constructor is being invoked, just that. However, in JavaScript, we didn\u2019t have class syntax until ES6 but still inherited the <code>this<\/code> keyword. My problem with <code>this<\/code> is it can be four different things depending on where is invoked!<\/p>\n<h4 id=\"1-this-in-the-function-invocation-pattern\">1. <code>this<\/code> In The Function Invocation Pattern<\/h4>\n<p>When <code>this<\/code> is invoked inside a function call, it will be bound to the global object. It will also be bound to the global object if it\u2019s invoked from the global scope.<\/p>\n<pre><code class=\"language-javascript\">console.log(this); \/\/ window\n\nfunction myFunction() {\n console.log(this);\n}\n\nmyFunction(); \/\/ window\n<\/code><\/pre>\n<p>In strict mode and through the function invocation pattern, <code>this<\/code> will be <code>undefined<\/code>.<\/p>\n<pre><code class=\"language-javascript\">function getThis() {\n \"use strict\";\n\n return this;\n}\n\ngetThis(); \/\/ undefined\n<\/code><\/pre>\n<h4 id=\"2-this-in-the-method-invocation-pattern\">2. <code>this<\/code> In The Method Invocation Pattern<\/h4>\n<p>If we reference a function as an object\u2019s property, <code>this<\/code> will be bound to its parent object.<\/p>\n<pre><code class=\"language-javascript\">const dog = {\n name: \"Sparky\",\n\n bark: function () {\n console.log(`Woof, my name is ${this.name}.`);\n },\n};\n\ndog.bark(); \/\/ Woof, my name is Sparky.\n<\/code><\/pre>\n<p>Arrow functions do not have their own <code>this<\/code>, but instead, they inherit <code>this<\/code> from their parent scope at creation.<\/p>\n<pre><code class=\"language-javascript\">const dog = {\n name: \"Sparky\",\n\n bark: () => {\n console.log(`Woof, my name is ${this.name}.`);\n },\n};\n\ndog.bark(); \/\/ Woof, my name is undefined.\n<\/code><\/pre>\n<p>In this case, <code>this<\/code> was bound to the global object instead of <code>dog<\/code>, hence <code>this.name<\/code> is <code>undefined<\/code>.<\/p>\n<h4 id=\"3-the-constructor-invocation-pattern\">3. The Constructor Invocation Pattern<\/h4>\n<p>If we invoke a function with the <code>new<\/code> prefix, a new empty object will be created, and <code>this<\/code> will be bound to that object.<\/p>\n<pre><code class=\"language-javascript\">function Dog(name) {\n this.name = name;\n\n this.bark = function () {\n console.log(`Woof, my name is ${this.name}.`);\n };\n}\n\nconst myDog = new Dog(\"Coco\");\n\nmyDog.bark(); \/\/ Woof, my name is Coco.\n<\/code><\/pre>\n<p>We could also employ <code>this<\/code> from the function\u2019s prototype to access the object\u2019s properties, which could give us a more valid reason to use it.<\/p>\n<pre><code class=\"language-javascript\">function Dog(name) {\n this.name = name;\n}\n\nDog.prototype.bark = function () {\n console.log(`Woof, my name is ${this.name}.`);\n};\n\nconst myDog = new Dog(\"Coco\");\n\nmyDog.bark(); \/\/ Woof, my name is Coco.\n<\/code><\/pre>\n<h4 id=\"4-the-apply-invocation-pattern\">4. The <code>apply<\/code> Invocation Pattern<\/h4>\n<p>Lastly, each function inherits an <code>apply<\/code> method from the function prototype that takes two parameters. The first parameter is the value that will be bound to <code>this<\/code> inside the function, and the second is an array that will be used as the function parameters.<\/p>\n<pre><code class=\"language-javascript\">\/\/ Bounding `this` to another object\n\nfunction bark() {\n console.log(`Woof, my name is ${this.name}.`);\n}\n\nconst myDog = {\n name: \"Milo\",\n};\n\nbark.apply(myDog); \/\/ Woof, my name is Milo.\n\n\/\/ Using the array parameter\n\nconst numbers = [3, 10, 4, 6, 9];\n\nconst max = Math.max.apply(null, numbers);\n\nconsole.log(max); \/\/ 10\n<\/code><\/pre>\n<p>As you can see, <code>this<\/code> can be almost anything and shouldn\u2019t be in JavaScript in the first place. Approaches like using <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Function\/bind\"><code>bind()<\/code><\/a> are solutions to a problem that shouldn\u2019t even exist. Fortunately, <code>this<\/code> is completely avoidable in modern JavaScript, and you can save yourself several headaches if you learn how to dodge it; an advantage that ES6 class users can\u2019t enjoy.<\/p>\n<p>Crockford has a nice anecdote on the topic from his book:<\/p>\n<blockquote><p>\u201cThis is a demonstrative pronoun. Just having <code>this<\/code> in the language makes the language harder to talk about. It is like pair programming with Abbott and Costello.\u201d<\/p><\/blockquote>\n<p><em>\u201cBut if we want to create a function constructor, we will need to use <code>this<\/code>.\u201d<\/em> Not necessarily! In the following example, we can make a function constructor that doesn\u2019t use <code>this<\/code> or <code>new<\/code> to work.<\/p>\n<pre><code class=\"language-javascript\">function counterConstructor() {\n let counter = 0;\n\n function getCounter() {\n return counter;\n }\n\n function up() {\n counter += 1;\n\n return counter;\n }\n\n function down() {\n counter -= 1;\n\n return counter;\n }\n\n return {\n getCounter,\n\n up,\n\n down,\n };\n}\n\nconst myCounter = counterConstructor();\n\nmyCounter.up(); \/\/ 1\n\nmyCounter.down(); \/\/ 0\n<\/code><\/pre>\n<p>We just created a function constructor without using <code>this<\/code> or <code>new<\/code>! And it comes with a straightforward syntax. A downside you could see is that objects created from <code>counterConstructor<\/code> won\u2019t have access to its prototype, so we can\u2019t add methods or properties from <code>counterConstructor.prototype<\/code>.<\/p>\n<p>But do we need this? Of course, we will need to reuse our code, but there are better approaches that we will see later.<\/p>\n<h3 id=\"the-new-prefix\">The <code>new<\/code> Prefix<\/h3>\n<p>In <em>JavaScript: The Good Parts<\/em>, Crockford argues that we shouldn\u2019t use the <code>new<\/code> prefix simply because there is no guarantee that we will remember to use it in the intended functions. I think that it\u2019s an easy-to-spot mistake and also avoidable by capitalizing the constructor functions you intend to use with <code>new<\/code>. And nowadays, linters will warn us when we call a capitalized function without <code>new<\/code>, or vice-versa.<\/p>\n<p>A better argument is simply that using <code>new<\/code> forces us to use <code>this<\/code> inside our constructor functions or \u201cclasses,\u201d and as we saw earlier, we are better off avoiding <code>this<\/code> in the first place.<\/p>\n<h3 id=\"the-multiple-ways-to-access-prototypes\">The Multiple Ways To Access Prototypes<\/h3>\n<p>For the historical reasons we already reviewed, we can understand why JavaScript doesn\u2019t embrace its prototypes. By extension, we don\u2019t have tools to mingle with prototypes as straightforward as we would want, but rather devious attempts to manipulate the prototype chain. Things get worse when across documentation, we can read different jargon around prototypes.<\/p>\n<h4 id=\"the-difference-between-prototype-proto-and-prototype\">The Difference Between <code>[[Prototype]]<\/code>, <code>__proto__<\/code>, And <code>.prototype<\/code><\/h4>\n<p>To make the reading experience more pleasant, let\u2019s go over the differences between these terms.<\/p>\n<ul>\n<li><strong><code>[[Prototype]]<\/code><\/strong> is an internal property that holds a reference to the object\u2019s prototype. It\u2019s enclosed in double square brackets, which means it typically cannot be accessed using normal notation.<\/li>\n<li><strong><code>__proto__<\/code><\/strong> can refer to two possible properties:\n<ul>\n<li>It can refer to a property from any <code>Object.prototype<\/code> object that exposes the hidden <code>[[Prototype]]<\/code> property. It\u2019s deprecated and ill-performing.<\/li>\n<li>It can refer to an optional property we can add when creating an object literal. The object\u2019s prototype will point to the value we give it.<\/li>\n<\/ul>\n<\/li>\n<li><strong><code>.prototype<\/code><\/strong> is a property exclusive to functions or classes (excluding arrow functions). When invoked using the <code>new<\/code> prefix, the instantiated object\u2019s prototype will point to the function\u2019s <code>.prototype<\/code>.<\/li>\n<\/ul>\n<p>We can now see all the ways we can modify prototypes in JavaScript. After reviewing, we will notice they all fall short in at least some aspect.<\/p>\n<h3 id=\"using-the-proto-literal-property-at-initialization\">Using The <code>__proto__<\/code> Literal Property At Initialization<\/h3>\n<p>When creating a JavaScript object using object literals, we can add a <code>__proto__<\/code> property. The created object will point its <code>[[Prototoype]]<\/code> to the value given in <code>__proto__<\/code>. In a prior example, objects created from our function constructor didn\u2019t have access to the constructor prototype. We can use the <code>__proto__<\/code> property at initialization to change this without using <code>this<\/code> or <code>new<\/code>.<\/p>\n<pre><code class=\"language-javascript\">function counterConstructor() {\n let counter = 0;\n\n function getCounter() {\n return counter;\n }\n\n function up() {\n counter += 1;\n\n return counter;\n }\n\n function down() {\n counter -= 1;\n\n return counter;\n }\n\n return {\n getCounter,\n\n up,\n\n down,\n\n __proto__: counterConstructor.prototype,\n };\n}\n<\/code><\/pre>\n<p>The advantage of linking the new object\u2019s prototype to the function constructor would be that we can extend its methods from the constructor prototype. But what good would it be if we needed to use <code>this<\/code> again?<\/p>\n<pre><code class=\"language-javascript\">const myCounter = counterConstructor();\n\ncounterConstructor.prototype.printDouble = function () {\n return this.getCounter() * 2;\n};\n\nmyCounter.up(); \/\/ 1\n\nmyCounter.up(); \/\/ 2\n\nmyCounter.printDouble(); \/\/ 4\n<\/code><\/pre>\n<p>We didn\u2019t even modify the <code>count<\/code> internal value but instead printed it double. So, a setter method would be necessary to manipulate its state from outside the initial function constructor declaration. However, we are over-complicating our code since we could have simply added a <code>double<\/code> method inside our function.<\/p>\n<pre><code class=\"language-javascript\">function counterConstructor() {\n let counter = 0;\n\n function getCounter() {\n return counter;\n }\n\n function up() {\n counter += 1;\n\n return counter;\n }\n\n function down() {\n counter -= 1;\n\n return counter;\n }\n\n function double() {\n counter = counter * 2;\n\n return counter;\n }\n\n return {\n getCounter,\n\n up,\n\n down,\n\n double,\n };\n}\n\nconst myCounter = counterConstructor();\n\nmyCounter.up(); \/\/ 1\n\nmyCounter.up(); \/\/ 2\n\nmyCounter.double(); \/\/ 4\n<\/code><\/pre>\n<p>Using <code>__proto__<\/code> is overkill in practice.<\/p>\n<p>It\u2019s vital to note that <code>__proto__<\/code> must only be used when initializing a new object through an object literal. Using the <code>__proto__<\/code> accessor in <code>Object.prototype.__proto__<\/code> will change the object\u2019s <code>[[Prototoype]]<\/code> after initialization, disrupting lots of optimizations done under the hood by JavaScript engines. That\u2019s why <strong><code>Object.prototype.__proto__<\/code> is ill-performant and deprecated<\/strong>.<\/p>\n<h4 id=\"object-create\"><code>Object.create()<\/code><\/h4>\n<p><code>Object.create()<\/code> returns a new object whose <code>[[Prototype]]<\/code> will be the first argument of the function. It also has a second argument that lets you define additional properties to the new objects. However, it\u2019s more flexible and readable to create an object using an object literal. Hence, its only practical use would be to create an object without a prototype using <code>Object.create(null)<\/code> since all objects created using object literals are automatically linked to <code>Object.prototype<\/code>.<\/p>\n<h4 id=\"object-setprototypeof\"><code>Object.setPrototypeOf()<\/code><\/h4>\n<p><code>Object.setPrototypeOf()<\/code> takes two objects as arguments and will mutate the prototype chain from the former argument to the latter. As we saw earlier, switching an object\u2019s prototype after initialization is ill-performing, so avoid it at all costs.<\/p>\n<h3 id=\"encapsulation-and-private-classes\">Encapsulation And Private Classes<\/h3>\n<p>My last argument against classes is the lack of privacy and encapsulation. Take, for example, the following class syntax:<\/p>\n<pre><code class=\"language-javascript\">class Cat {\n constructor(name) {\n this.name = name;\n }\n\n meow() {\n console.log(`Meow! My name is ${this.name}.`);\n }\n}\n\nconst myCat = new Cat(\"Gala\");\n\nmyCat.meow(); \/\/ Meow! My name is Gala.\n\nmyCat.name = \"Pumpkin\";\n\nmyCat.meow(); \/\/ Meow! My name is Pumpkin.\n<\/code><\/pre>\n<p>We don\u2019t have any privacy! All properties are public. We can try to mitigate this with closures:<\/p>\n<pre><code class=\"language-javascript\">class Cat {\n constructor(name) {\n this.getName = function () {\n return name;\n };\n }\n\n meow() {\n console.log(`Meow! My name is ${this.name}.`);\n }\n}\n\nconst myCat = new Cat(\"Gala\");\n\nmyCat.meow(); \/\/ Meow! My name is undefined.\n<\/code><\/pre>\n<p>Oops, now <code>this.name<\/code> is <code>undefined<\/code> outside the constructor\u2019s scope. We have to change <code>this.name<\/code> to <code>this.getName()<\/code> so it can work properly.<\/p>\n<pre><code class=\"language-javascript\">class Cat {\n constructor(name) {\n this.getName = function () {\n return name;\n };\n }\n\n meow() {\n console.log(`Meow! My name is ${this.getName()}.`);\n }\n}\n\nconst myCat = new Cat(\"Gala\");\n\nmyCat.meow(); \/\/ Meow! My name is Gala.\n<\/code><\/pre>\n<p>This is with only one argument, so you can imagine how unnecessarily repetitive our code would be the more arguments we add. Besides, we can still modify our object methods:<\/p>\n<pre><code class=\"language-javascript\">myCat.meow = function () {\n console.log(`Meow! ${this.getName()} is a bad kitten.`);\n};\n\nmyCat.meow(); \/\/ Meow! Gala is a bad kitten.\n<\/code><\/pre>\n<p>We can save and implement better privacy if we use our own function constructors and even make our methods immutable using <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Object\/freeze\"><code>Object.freeze()<\/code><\/a>!<\/p>\n<pre><code class=\"language-javascript\">function catConstructor(name) {\n function getName() {\n return name;\n }\n\n function meow() {\n console.log(`Meow! My name is ${name}.`);\n }\n\n return Object.freeze({\n getName,\n\n meow,\n });\n}\n\nconst myCat = catConstructor(\"Loaf\");\n\nmyCat.meow(); \/\/ Meow! My name is Loaf.\n<\/code><\/pre>\n<p>And trying to modify the object\u2019s methods will fail silently.<\/p>\n<pre><code class=\"language-javascript\">myCat.meow = function () {\n console.log(`Meow! ${this.getName()} is a bad Kitten.`);\n};\n\nmyCat.meow(); \/\/ Meow! My name is Loaf.\n<\/code><\/pre>\n<p>And yes, I am aware of the recent proposal for <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes\/Private_class_fields\">private class fields<\/a>. But do we really need even <em>more<\/em> new syntax when we could accomplish the same using custom constructor functions and closures?<\/p>\n<div class=\"partners__lead-place\"><\/div>\n<h2 id=\"so-classes-or-prototypes-in-javascript\">So, Classes Or Prototypes In JavaScript?<\/h2>\n<p>In Crockford\u2019s more recent book, <a href=\"https:\/\/www.amazon.com\/dp\/1949815005\/wrrrldwideweb\"><em>How JavaScript Works<\/em><\/a> (<a href=\"https:\/\/www.crockford.com\/image\/howjsworks.pdf\">PDF<\/a>), we can see a better option than using Prototypes or Classes for code reuse: <strong>Composition<\/strong>!<\/p>\n<blockquote class=\"pull-quote\">\n<p>\n <a class=\"pull-quote__link\" aria-label=\"Share on Twitter\" href=\"https:\/\/twitter.com\/share?text=%0aUsing%20prototypes%20feels%20like%20using%20a%20half-finished%20feature,%20while%20classes%20can%20lead%20to%20overcomplicated%20and%20unnecessary%20hierarchies%20%28and%20also%20to%20%60this%60%20%29.%20Fortunately,%20JavaScript%20is%20a%20multi-paradigm%20language,%20and%20forcing%20ourselves%20to%20only%20use%20classes%20or%20prototypes%20for%20code%20reusability%20is%20constraining%20ourselves%20with%20imaginary%20ropes.%0a&url=https:\/\/smashingmagazine.com%2f2023%2f12%2fmarketing-changed-oop-javascript%2f\"><\/p>\n<p>Using prototypes feels like using a half-finished feature, while classes can lead to overcomplicated and unnecessary hierarchies (and also to `this` ). Fortunately, JavaScript is a multi-paradigm language, and forcing ourselves to only use classes or prototypes for code reusability is constraining ourselves with imaginary ropes.<\/p>\n<p> <\/a>\n <\/p>\n<div class=\"pull-quote__quotation\">\n<div class=\"pull-quote__bg\">\n <span class=\"pull-quote__symbol\">\u201c<\/span><\/div>\n<\/p><\/div>\n<\/blockquote>\n<p>As Crockford says in his more recent book:<\/p>\n<blockquote><p>\u201c[I]nstead of <strong>same as except<\/strong> we can get a <strong>little bit of this<\/strong> and <strong>a little bit of that<\/strong>.\u201d<\/p>\n<p>— Douglas Crockford, <a href=\"https:\/\/www.amazon.com\/dp\/1949815005\/wrrrldwideweb\"><em>How JavaScript Works<\/em><\/a><\/p><\/blockquote>\n<p>Instead of a function constructor or class inheriting from another, we can have a set of constructors and combine them when needed to create a specialized object.<\/p>\n<div class=\"break-out\">\n<pre><code class=\"language-javascript\">function speakerConstructor(name, message) {\n function talk() {\n return `Hi, mi name is ${name} and I want to tell something: ${message}.`;\n }\n\n return Object.freeze({\n talk,\n });\n}\n\nfunction loudSpeakerConstructor(name, message) {\n const {talk} = speakerConstructor(name, message);\n\n function yell() {\n return talk().toUpperCase();\n }\n\n return Object.freeze({\n talk,\n\n yell,\n });\n}\n\nconst mySpeaker = loudSpeakerConstructor(\"Juan\", \"You look nice!\");\n\nmySpeaker.talk(); \/\/ Hi, my name is Juan and I want to tell something: You look nice!\n\nmySpeaker.yell(); \/\/ HI, MY NAME IS JUAN AND I WANT TO TELL SOMETHING: YOU LOOK NICE!\n<\/code><\/pre>\n<\/div>\n<p>Without the need for <code>this<\/code> and <code>new<\/code> and classes or prototypes, we achieve a reusable function constructor with full privacy and encapsulation.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>Yes, JavaScript was made in 10 days in a rush; yes, it was tainted by marketing; and yes, it has a long set of useless and dangerous parts. Yet is a beautiful language and fuels a lot of the innovation happening in web development today, so it clearly has done something good!<\/p>\n<blockquote class=\"pull-quote\">\n<p>\n <a class=\"pull-quote__link\" aria-label=\"Share on Twitter\" href=\"https:\/\/twitter.com\/share?text=%0aI%20don%e2%80%99t%20think%20we%20will%20see%20a%20day%20when%20prototypes%20receive%20the%20features%20they%20deserve,%20nor%20one%20in%20which%20we%20stop%20using%20classical%20syntactic%20sugar,%20but%20we%20can%20decide%20to%20avoid%20them%20when%20possible.%0a&url=https:\/\/smashingmagazine.com%2f2023%2f12%2fmarketing-changed-oop-javascript%2f\"><\/p>\n<p>I don\u2019t think we will see a day when prototypes receive the features they deserve, nor one in which we stop using classical syntactic sugar, but we can decide to avoid them when possible.<\/p>\n<p> <\/a>\n <\/p>\n<div class=\"pull-quote__quotation\">\n<div class=\"pull-quote__bg\">\n <span class=\"pull-quote__symbol\">\u201c<\/span><\/div>\n<\/p><\/div>\n<\/blockquote>\n<p>Unfortunately, this conscious decision to stick to the good parts isn\u2019t exclusive to JavaScript OOP since, between the rush into existence, the language brought a lot of other dubious features that we are better off not using. Maybe we can tackle them in a future article, but in the meantime, we will have to acknowledge their presence and make the conscious decision to keep learning and understanding the language to know which parts to use and which parts to ignore.<\/p>\n<h3 id=\"references\">References<\/h3>\n<ul>\n<li><a href=\"https:\/\/brendaneich.com\/\">Brendan Eich Personal Website<\/a> (N.D.)<\/li>\n<li><a href=\"https:\/\/www.amazon.com\/Douglas-Crockford\/dp\/0596517742\"><em>JavaScript: The Good Parts<\/em><\/a>, Douglas Crockford (O\u2019Reilly, 2008)<\/li>\n<li><a href=\"https:\/\/www.amazon.com\/Douglas-Crockford-ebook\/dp\/B07NLM78D9\/\"><em>How JavaScript Works<\/em><\/a>, Douglas Crockford (Virgule-Solidus, 2018)<\/li>\n<li><a href=\"https:\/\/crockford.com\/javascript\/\">Douglas Crockford Personal Website<\/a> (N.D.)<\/li>\n<li><a href=\"https:\/\/www.infoworld.com\/video\/89115\/javascript-creator-brendan-eich-on-the-genesis-of-the-popular-programming-language-true-technologis\">Brendan Eich\u2019s Interview Conducted by Eric Knorr<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=krB0enBeSiE\">Brendan Eich\u2019s Interview Conducted by Lex Fridman<\/a><\/li>\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\">Mozilla Foundation Documentation<\/a> (N.D.)<\/li>\n<\/ul>\n<div class=\"signature\">\n <img decoding=\"async\" src=\"https:\/\/www.smashingmagazine.com\/images\/logo\/logo--red.png\" alt=\"Smashing Editorial\" width=\"35\" height=\"46\" loading=\"lazy\" \/><br \/>\n <span>(gg, yk)<\/span>\n<\/div>\n<\/article>\n","protected":false},"excerpt":{"rendered":"<p>How Marketing Changed OOP In JavaScript How Marketing Changed OOP In JavaScript Juan Diego Rodr\u00edguez 2023-12-04T14:00:00+00:00 2024-06-12T20:05:40+00:00 Even though JavaScript\u2019s name was coined from the Java language, the two languages<\/p>\n<p class=\"more-link\"><a href=\"http:\/\/sobre-portugal.com\/index.php\/2023\/12\/04\/how-marketing-changed-oop-in-javascript\/\" class=\"readmore\">Continue reading<svg class=\"icon icon-arrow-right\" aria-hidden=\"true\" role=\"img\"> <use href=\"#icon-arrow-right\" xlink:href=\"#icon-arrow-right\"><\/use> <\/svg><span class=\"screen-reader-text\">How Marketing Changed OOP In JavaScript<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-391","post","type-post","status-publish","format-standard","hentry","category-javascript"],"_links":{"self":[{"href":"http:\/\/sobre-portugal.com\/index.php\/wp-json\/wp\/v2\/posts\/391","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/sobre-portugal.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/sobre-portugal.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/sobre-portugal.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/sobre-portugal.com\/index.php\/wp-json\/wp\/v2\/comments?post=391"}],"version-history":[{"count":1,"href":"http:\/\/sobre-portugal.com\/index.php\/wp-json\/wp\/v2\/posts\/391\/revisions"}],"predecessor-version":[{"id":392,"href":"http:\/\/sobre-portugal.com\/index.php\/wp-json\/wp\/v2\/posts\/391\/revisions\/392"}],"wp:attachment":[{"href":"http:\/\/sobre-portugal.com\/index.php\/wp-json\/wp\/v2\/media?parent=391"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/sobre-portugal.com\/index.php\/wp-json\/wp\/v2\/categories?post=391"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/sobre-portugal.com\/index.php\/wp-json\/wp\/v2\/tags?post=391"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}