{"id":4716,"date":"2018-05-22T14:27:47","date_gmt":"2018-05-22T14:27:47","guid":{"rendered":"https:\/\/tinjurewp.com\/jsblog\/?p=1204"},"modified":"2018-05-22T14:27:47","modified_gmt":"2018-05-22T14:27:47","slug":"learning-javascript-classes","status":"publish","type":"post","link":"https:\/\/learncode.tinjurewp.com\/learning-javascript-classes\/","title":{"rendered":"Learning JavaScript Classes"},"content":{"rendered":"<p class=\"note\"><strong>Note<\/strong>: This post is work-in-progress learning-note and still in active development and updated regularly.<\/p>\n<p>JavaScript is a Object Oriented language. Unlike other language (eg. C++, Java, Python etc) JS is not class-based nevertheless\u00a0 Objects in JavaScript are considered everything. In ES2015 (ES6), a prototype-based <code>class<\/code> keyword was introduced. In this learning note we will deep dive into JS <code>class<\/code>, its common uses with a focus on its relation to prototypes.<\/p>\n<blockquote><p>Under the hood, ES6 classes are not something that is radically new: They mainly provide more convenient syntax to create old-school constructor functions.<cite>\u00a0 <a href=\"http:\/\/exploringjs.com\/es6\/ch_classes.html\" target=\"_blank\" rel=\"noopener\">Axel Rauschmayer<\/a><\/cite><\/p><\/blockquote>\n<p>JavaScript <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes\" target=\"_blank\" rel=\"noopener\">classes<\/a> are &#8220;special function&#8221; which can be <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Defining_classes\" target=\"_blank\" rel=\"noopener\">defined<\/a> as <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Class_expressions\" target=\"_blank\" rel=\"noopener\">class expression<\/a> or <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Class_declarations\" target=\"_blank\" rel=\"noopener\">class declaration<\/a> similar to to <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Guide\/Functions#Defining_functions\" target=\"_blank\" rel=\"noopener\">defining functions.<\/a><\/p>\n<h3>Function vs Class<\/h3>\n<p>In order to understand JS classes are special functions, lets create a simple <code>Vehicle<\/code> function using both <code>function()<\/code> syntax and <code>class<\/code> syntax below and examine differences between the two methods:<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/ Initialize Vehicle function\nfunction Vehicle(make, model) {     \/\/function declaration\n  this.make= make;                  \/\/ define properties\n  this.model= model;\n}\n\/\/method declaration\nVehicle.prototype.reminder = function() {  \/\/method declaration\n  console.log(this.make);\n}\n\/\/create myVehicle instance\nlet myVehicle = new Vehicle(&quot;Ford&quot;); \/\/create myVehicle instance (new&#039; keyword)\nmyVehicle.reminder();                \/\/Output =&gt; Ford<\/code><\/pre>\n<p>In the example above, we created a <code>Vehicle()<\/code> function (line 2)with two properties (<code>make<\/code>, <code>model<\/code>). Using o<code>bject.prototype._<\/code> we created a <code>reminder()<\/code> method (line 7). Lastly, <code>myVehicle<\/code> object instance was created (line 11) using <code>new<\/code> keyword and expected output was displayed (line 12).<\/p>\n<p>Prototype ( <code>[[Prototype]]<\/code> ) of <code>vehicle()<\/code> function can be accessed using the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Object\/getPrototypeOf\"><code>Object.getPrototypeOf()<\/code> method<\/a> as follows:<\/p>\n<pre class=\"line-numbers\" data-start=\"13\"><code class=\"language-javascript\">\/\/access prototype of Vehicle function\nObject.getPrototypeOf(Vehicle);\n\/\/\u0192 () { [native code] }\n\nObject.getPrototypeOf(myVehicle);\n\/\/{reminder: \u0192, constructor: \u0192}<\/code><\/pre>\n<p>With prototype-based language, any function can become a constructor instance using the <code>new<\/code> keyword (line 18).<\/p>\n<p>In the example below, lets initialize the above <code>Vehicle<\/code> object with same properties and methods using <code>class<\/code> syntax.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/ initialize Vehicle class\nclass Vehicle {               \/\/ class declaration\n  constructor(make, model) {  \/\/constructor declaration\n    this.make = make;         \/\/ instance variables\n    this.model= model;\n  }\n\/\/ method declaration\n  reminder() {               \/\/ method declaration\n    console.log(this.make);\n  }\n}\n\/\/Create myVehicle instance\nlet myVehicle = new Vehicle(&quot;Ford&quot;); \/\/ object instance (&#039;new&#039; keyword)\nmyVehicle.reminder();                \/\/OUTPUT =&gt; Ford<\/code><\/pre>\n<p>Lets also look at the <code>vehicle()<\/code> object created with <code>class<\/code> construct using the same <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Object\/getPrototypeOf\"><code>Object.getPrototypeOf()<\/code> method<\/a>:<\/p>\n<pre class=\"line-numbers\" data-start=\"15\"><code class=\"language-javascript\">\/\/access prototype of Vehicle class\nObject.getPrototypeOf(Vehicle);\n\/\/\u0192 () { [native code] }\n\nObject.getPrototypeOf(myVehicle);\n\/\/{constructor: \u0192, reminder: \u0192}<\/code><\/pre>\n<p>Similar to the function, object instances created with <code>new<\/code> keyword also become a constructor instance as shown in the example above.<\/p>\n<p>From the above two examples, we got the same output demonstrating that JS class are functions, but creating method with <code>class<\/code> keyword is much simpler (lines 8-10) and easier to read.<\/p>\n<h3>Defining Classes<\/h3>\n<p>Before defining objects using <code>class<\/code> keyword, lets revisit some <strong>terminologies<\/strong> that are used in JS classes.<\/p>\n<ul>\n<li><strong>Class<\/strong>: Classes are &#8220;special <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Functions\">functions<\/a>&#8220;, that are used to define objects properties &amp; methods.<\/li>\n<li><strong>Object<\/strong>: It is a class instance and may include combination of data structure, variables and function.<\/li>\n<li><strong>Method<\/strong>: It&#8217;s function defined in a class object introduced in ES6<\/li>\n<li><strong>Constructor:<\/strong> The <code>constructor<\/code> is a special method for creating and initializing an object in a <code>class<\/code>. It is invoked when an object instance is created.<\/li>\n<\/ul>\n<h5>Class Declaration<\/h5>\n<p>In our previous example, we use <code>vehicle<\/code> object example. Lets use the same object to define using <code>classes<\/code>. Just like in f<em>unction declaration<\/em>, classes are declared as using <code>class<\/code> keyword followed by an identifier and code block inside <code>{\u00a0 }<\/code> called <em>class body<\/em>.<\/p>\n<h6>Class Declaration Syntax<\/h6>\n<p>A class object can be defined by <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Class_declarations\" target=\"_blank\" rel=\"noopener\">class declaration<\/a> using <code>class<\/code> keyword followed by name of class. A simple <em>class declaration<\/em> syntax is shown below:<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/initialize vehicle object\nclass Vehicle {\n  constructor(make, model, year) {\n    this.make = make;\n    this.model = model;\n    this.year = year;\n  }\n}\n\/\/retrive\nconsole.log(Vehicle.name);\n\/\/OUTPUT =&gt; Vehicle<\/code><\/pre>\n<p>In the example above, in line 2 a <code>Vehicle<\/code> class was declared as <code>class Vehicle { }<\/code>. Unlike in function declaration, in class declaration <strong><code>constructor<\/code><\/strong> keyword is used to initialize object&#8217;s properties. Some key features of <code>constructor<\/code> function:<\/p>\n<ul>\n<li>Class <code>constructor<\/code>, which initializes object instance) holds only method definitions and not data properties;<\/li>\n<li>In ES6, methods are defined using <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Functions\/Method_definitions\" target=\"_blank\" rel=\"noopener\">shorter syntax<\/a> (similar to <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Functions\/get\" target=\"_blank\" rel=\"noopener\">getter<\/a> and <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Functions\/set\" target=\"_blank\" rel=\"noopener\">setter<\/a> syntax of ES5);<\/li>\n<li>Methods definitions in class bodies are NOT separated by ( <code>&#039;<\/code> ) comma;<\/li>\n<li>Properties on class instance can be directly invoked as shown in line\u00a0 ;<\/li>\n<li>There can only be a single <code>constructor<\/code> method associated with a class.<\/li>\n<\/ul>\n<p class=\"tip icon-tip\"><strong>Tip<\/strong>: Class declarations where <code>extends<\/code> keywords are not used to create sub-classes are known as <strong><em>base classes<\/em><\/strong><\/p>\n<p>In the following example (borrowed from <a href=\"https:\/\/scotch.io\/tutorials\/better-javascript-with-es6-pt-ii-a-deep-dive-into-classes#base-classes-declarations-expressions\" target=\"_blank\" rel=\"noopener\">Peleke Sengstacke&#8217; article<\/a>) the above <code>Vehicle<\/code> object expanded to include four properties and two methods <code>toString()<\/code> and <code>reminder()<\/code>.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/ vehicle is a base class\nclass Vehicle {\n    constructor (make, year, color) {\n        this.make = make;\n        this.year = year;\n        this.color = color;\n    }\n\/\/ create method toString\n    toString () {\n        return `Bring your ${this.color} ${this.make} (${this.year}) to dealer.`\n    }\n\/\/ create method reminder\n    reminder () {\n      console.log( this.toString() );\n    }\n}\n\/\/initialize myCar object instance\nconst myCar = new Vehicle(&#039;Toyota&#039;, 2018, &#039;black&#039;);\n\/\/Invoking object instance \nmyCar.reminder(); \/\/OUTPUT =&gt; Bring your black Toyota (2018) to dealer. \nconsole.log(myCar.color); \/\/OUTPUT =&gt; Black<\/code><\/pre>\n<p>In the example above, a <code>Vehicle<\/code> object was initialize using <code>class<\/code> (line 2) was initialized to create <code>myCar<\/code> object instance using <code>new<\/code> keyword (line 19) with values (<code>&#039;Toyota&#039;<\/code>, <code>2018<\/code>, <code>&#039;black&#039;<\/code>) for the constructor function properties defined\u00a0 (lines 3-7) as arguments (line 19). When the new object instance <code>myCar<\/code> was invoked, we got expected output (lines 12-13). Please take a note that <code>Vehicle<\/code> class property defined in (line ) can be directly referred with <code>myCar<\/code> instance as shown in output (line 21).<\/p>\n<p>To quote\u00a0from <a href=\"https:\/\/scotch.io\/tutorials\/better-javascript-with-es6-pt-ii-a-deep-dive-into-classes#base-classes-declarations-expressions\" target=\"_blank\" rel=\"noopener\">Peleke&#8217;s article<\/a>, some key features of class declaration include:<\/p>\n<ul>\n<li>Classes can <em>only<\/em> contain method definitions, <strong>not<\/strong> data properties;<\/li>\n<li>When defining methods, you use <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Functions\/Method_definitions\" target=\"_blank\" rel=\"noopener\">shorthand method definitions<\/a>;<\/li>\n<li>Unlike when creating objects, you do <em>not<\/em> separate method definitions in class bodies with commas; and<\/li>\n<li>You <em>can<\/em> refer to properties on instances of the class directly<\/li>\n<\/ul>\n<p class=\"tip icon-tip\"><strong>Tip<\/strong>: Class declaration without <code>extends<\/code> keyword are known as <strong>base classes<\/strong>.<\/p>\n<h5>Class Expression<\/h5>\n<p>Classes are also initialized using <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/class\" target=\"_blank\" rel=\"noopener\">class expression<\/a>, where a class is assigned to a variable.\u00a0 Just like in <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/function\" target=\"_blank\" rel=\"noopener\">function expression<\/a>, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/class\" target=\"_blank\" rel=\"noopener\">class expression<\/a> can be named or unnamed. Since JS classes are prototype-based inheritance, if class expression is named, the name attribute of the class is local property to the <em>class body<\/em> only.<\/p>\n<h6>Class Expression Syntax<\/h6>\n<p>The following example shows basic syntax of defining a <code>Vehicle<\/code> object with <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Class_expressions\" target=\"_blank\" rel=\"noopener\">class expression<\/a>. This is similar to defining <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/function\" target=\"_blank\" rel=\"noopener\">anonymous and named function expression<\/a>.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/ unnamed class\nlet Vehicle = class {\n  constructor(make, model, year) {\n    this.make = make;\n    this.model = model;\n    this.year = year;\n  }\n};\nconsole.log(Vehicle.name);\n\/\/ OUTPUT =&gt; Vehicle\n\n\/\/ named class\nlet Vehicle= class Truck {\n  constructor(make, model, year) { \n    this.make = make;\n    this.model = model;\n    this.year = year;\n  }\n};\n\/\/retrieve\nconsole.log(Vehicle.name);\n\/\/ OUTPUT =&gt; Truck<\/code><\/pre>\n<p>In the example above, <code>Vehicle<\/code> object was defined with <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Class_expressions\" target=\"_blank\" rel=\"noopener\">class expression<\/a>, just like a <em>function<\/em> is defined using <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Guide\/Functions#Function_expressions\" target=\"_blank\" rel=\"noopener\">function expression<\/a>. The <code>Vehicle<\/code> object was assigned to a variable and class on the right side of assignment expression ( <code>=<\/code> ). Just like in functions, class expression can be anonymous (unnamed) (line 2) or with a name (eg. <code>Truck<\/code>) after <code>class<\/code> keyword (line 13). As <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Class_expressions\" target=\"_blank\" rel=\"noopener\">MDN states<\/a>, <em>the name given to a named class expression is local to the class&#8217;s body and can be retrieved through the class&#8217;s (not an instance&#8217;s)<code> .name<\/code> property<\/em>.<\/p>\n<p>Lets revisit the <code>Vehicle<\/code> object that we defined in previous section with <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Class_declarations\" target=\"_blank\" rel=\"noopener\">class declaration<\/a> and define with <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Class_expressions\" target=\"_blank\" rel=\"noopener\">class expression<\/a> as shown below:<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/ initialize Vehicle class\nlet Vehicle = class {\n  constructor (make, year, color) {\n        this.make = make;\n        this.year = year;\n        this.color = color;\n    }     \n  \/\/initialize method\n   toString () {\n        return `Bring your ${this.color} ${this.make}(${this.year}) to dealer.`\n     }\n\/\/initialize method\n   reminder () {\n      console.log( this.toString() );\n    }\n};\n \/\/initialize myCar instance with new keyword\nlet myCar = new Vehicle(&#039;Toyota&#039;, 2018, &#039;black&#039;);\n\/\/invoke myCar instance\nmyCar.reminder(); \/\/OUTPUT =&gt; Bring your black Toyota (2018) to dealer.\nconsole.log(myCar.color);  \/\/OUTPUT =&gt; Black<\/code><\/pre>\n<p>The example above, an unnamed <code>class<\/code> was defined and assigned as to an <code>Vehicle<\/code> object variable using <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Class_expressions\" target=\"_blank\" rel=\"noopener\">class expression<\/a> syntax. As expected its output is exactly same.<\/p>\n<h3>Methods Definitions<\/h3>\n<h6>Strict Mode<\/h6>\n<p>As <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Strict_mode\" target=\"_blank\" rel=\"noopener\">MDN Describes it<\/a>, <em>the bodies of class <strong>declarations<\/strong> and <strong>class expressions<\/strong> are executed in <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Strict_mode\">strict mode<\/a> i.e. constructor, static and prototype methods, getter and setter functions are executed in strict mode<\/em>.<\/p>\n<h5>Prototype Method<\/h5>\n<p>These methods can be invoked as instance of an class object. It&#8217;s cleaner and more readable. Lets revisit the <code>Vehicle<\/code> class defined earlier under Class Declaration section.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/Using ES6 syntax \n\/\/initialize Vehicle class\nclass Vehicle {\n  constructor (make, model, year) {\n        this.make = make;\n        this.model = model;\n        this.year = year;\n    }     \n  \/\/initialise method\n   toString () {\n        return `Bring your ${this.make} ${this.model} (${this.year}) to dealer.`\n     }\n\/\/initialize method\n   reminder () {\n      console.log( this.toString() );\n    }\n};\n\/\/initialize myCar object instance\nconst myCar = new Vehicle(&#039;Toyota&#039;, &#039;Camry&#039;, 2018, &#039;black&#039;);\n\/\/invoke myCar\nmyCar.reminder(); \/\/OUTPUT =&gt; Bring your Toyota Camry (2018) to dealer.<\/code><\/pre>\n<p>Before ES6, methods could only be defined using a constructor function. Its &#8216;prototype&#8217; name comes from ES5 syntax which has prototype inheritance. Lets initialize below the same <code>Vehicle<\/code> class using ES5 syntax.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/ Using ES5 syntax\n\/\/ Initialize Vehicle class\nfunction Vehicle (make, model, year)  {\n        this.make = make;\n        this.model = model;\n        this.year = year;\n    } \n\/\/ initialize methods\nVehicle.prototype.toString = function toString () {\n    return `Bring your ${this.make} ${this.model} (${this.year}) to dealer.` \n};\n\nVehicle.prototype.reminder = function reminder () {\n    console.log( this.toString() ); \n};\n\n\/\/initialize myCar object instance\nconst myCar = new Vehicle(&#039;Toyota&#039;, &#039;Camry&#039;, 2018, &#039;black&#039;);\n\/\/invoke myCar\nmyCar.reminder(); \/\/OUTPUT =&gt; Bring your Toyota Camry (2018) to dealer.<\/code><\/pre>\n<p>The methods defined in <code>Vehicle()<\/code> function above is same as <code>Vehicle<\/code> class defined earlier. Syntax used in defining methods in ES5 is longer (lines: 9-15) compared to ES6 syntax.<\/p>\n<p>With ES6, <code>Accessor<\/code> Descriptors (<code>Getter<\/code> and <code>setter<\/code>) can also be used to define prototype methods of class function.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/initialize Vehicle class\nclass Vehicle { \n  constructor (make, model) {\n    this.make = make;\n    this.model = model;  \n  }     \n  \n  \/\/initialise msg method\n   message () {       \n    return `Bring your ${this.make} ${this.model} to dealer.`    \n  }\n  \/\/using get accessor method\n  get reminder() {   \n    return this.myReminder();\n  }\n  \/\/initialize myRemindermethod\n  myReminder () {   \n   console.log( this.message() ); \n  }\n};\n\/\/initialize myCar object instance\nconst myCar = new Vehicle(&#039;Toyota&#039;, &#039;Camry&#039;);\n\/\/invoke myCar.myReminder()\nconsole.log(myCar.myReminder());\n\/\/OUTPUT\nBring your Toyota Camry to dealer.<\/code><\/pre>\n<p>In the example above, revisiting the <code>Vehicle<\/code> class function described above with <code>get<\/code> accessor descriptor method (line 13) we get the same exact output.<\/p>\n<p class=\"tip icon-note\">Note: More detail discussion about <code>accessor<\/code> descriptor properties are described in <a href=\"https:\/\/tinjurewp.com\/jsblog\/understanding-javascript-accessors-getters-setters\/\" target=\"_blank\" rel=\"noopener\">Understanding JavaScript Accessors: <code>Getters<\/code> &amp; <code>Setters<\/code> <\/a>learning-note post.<\/p>\n<h5>Constructor<\/h5>\n<p>As <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Constructor\" target=\"_blank\" rel=\"noopener\">MDN describes<\/a> it, <em>the constructor method is a special method for creating and initializing an object created within a class<\/em>. A typical constructor syntax:\u00a0 <code>constructor([arguments]) { ... }<\/code>.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">class Car {};\n\/\/access Car() with typeof\ntypeof Car; \/\/ &#039;function&#039;\n\n\/\/initialize Car class\nclass Car (make, model) {\n   this.make = make;\n   this.model = model;\n}\n\nlet myCar = Car(&quot;Toyota&quot;, &quot;Corolla&quot;);\nconsole.log(myCar); \/\/ SyntaxError\n\n\nfunction Car (make, model) {\n    this.name    = make;\n    this.protein = model;\n}\n\nconst myCar = Car(&#039;Toyota&#039;, &#039;Corolla&#039;); \nconsole.log(myCar); \/\/ undefined\n\n\/\/ creating new object instance with &#039;new&#039;\nlet myVehicle = new Vehicle(&#039;Toyota&#039;, &#039;Corolla&#039;);\nconsole.log(myVehicle); \n\/\/ OUTPUT =&gt; Vehicle {make: &quot;Toyota&quot;, model: &quot;Corolla&quot;}<\/code><\/pre>\n<p>There can only be one <code>constructor<\/code> method in a class; more than one constructor in a class through a <a title=\"The SyntaxError object represents an error when trying to interpret syntactically invalid code.\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/SyntaxError\"><code>SyntaxError<\/code><\/a> error.<\/p>\n<h5>Static Method<\/h5>\n<p><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes\/static\" target=\"_blank\" rel=\"noopener\">Static<\/a> methods for a class can be created using <code>static<\/code> keyword. Static methods are similar to prototype methods except that they are called called by a class. These methods <strong>cannot<\/strong> be called with a class <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Introduction_to_Object-Oriented_JavaScript#The_object_(class_instance)\" target=\"_blank\" rel=\"noopener\">instance.<\/a><\/p>\n<p>Static methods are commonly used to create utility functions on classes, for example methods that are common to all object.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/initialize Vehicle class\nclass Vehicle {              \/\/class declaration\n  constructor(make, model) {  \/\/ constructor declaration\n    this.make = make;\n    this.model = model;\n  }\n\/\/add static method\n static reminder() {       \/\/ static method declaration\n   console.log(`Bring your ${this.make} for tune up.`);\n }\n}\n\n\/\/invoke static method\nVehicle.reminder();\n\/\/OUTPUT =&gt; Bring your undefined for tune up.<\/code><\/pre>\n<p>In the example above, static method <code>reminder()<\/code> was created ( line 8) on class <code>Vehicle<\/code> (line 2). The static method <code>Vehicle.reminder()<\/code> was called directly (line 14) on class <code>Vehicle<\/code> without class instantiation. Expected output &#8221; <code>Bring your undefined for tune up<\/code> &#8221; was displayed without any error.<\/p>\n<h3>Sub Classing with <code>Extends<\/code><\/h3>\n<p><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Statements\/class\" target=\"_blank\" rel=\"noopener\">Class declarations<\/a> or <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/class\" target=\"_blank\" rel=\"noopener\">class expressions<\/a> can be extended using <code>extends<\/code> keyword to create child classes often called <strong>subclasses<\/strong> or <strong>derived classes<\/strong>. In subclasses, an object defined in parent class can be shared with subclass and its properties can be modified or added new ones. Some key features of subclass, as s<a href=\"https:\/\/scotch.io\/tutorials\/better-javascript-with-es6-pt-ii-a-deep-dive-into-classes\" target=\"_blank\" rel=\"noopener\">ummarized by Peleke<\/a> include:<\/p>\n<ul>\n<li>Subclasses are created from parent object using <code>class<\/code> keyword followed by another <code>extends<\/code> keyword (line ).<\/li>\n<li>The <code>super<\/code> keyword should be used to refer to parent class properties<\/li>\n<li>While referring to parental class, the constructor function in subclass should include parameters defined in parent class; can&#8217;t refer an empty constructor function in subclass.<\/li>\n<li>The <code>this<\/code> keyword can be used only after defining <code>super<\/code> keyword in the constructor function.<\/li>\n<\/ul>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/ initialize Vehicle class\nclass Vehicle {                               \n    constructor (make, model) {                    \n        this.make = make;                        \n        this.model = model;\n    }\n\/\/ define method\n    run () {                                \n        return `Fastest man alive ${this.model} &amp; ${this.model}`;\n    }\n}\n\/\/initialize subclass Hybrid Vehicle with extends\nclass HybridVehicle extends Vehicle {              \n    constructor(make, model, electric) {                  \n        super(make, model);                        \n        this.electric = electric;\n    }\n\/\/define method\n    fly () {                                \n        return `I&#039;m an alien ${this.model} &amp; ${this.model} + ${this.electric}`;\n    }\n}\n\/\/initiaze myHybrid object instance with new keyword\nconst myHybrid = new HybridVehicle(&#039;Toyota&#039;,&#039;Camry&#039;,&#039;hybrid&#039;);         \nconsole.log(myHybrid.run()); \n\/\/OUTPUT =&gt; Fastest man alive Camry &amp; Camry\nconsole.log(myHybrid.fly()); \n\/\/OUTPUT =&gt; I&#039;m an alien Camry &amp; Camry + hybrid\n\n\/\/output\nmyHybrid.run(); \/\/OUTPUT=&gt; &quot;Fastest man alive Camry &amp; Camry&quot;<\/code><\/pre>\n<p>In the above example, we created a subclass named <code>HybridVehicle<\/code> using <code>extends<\/code> keyword from its parent class <code>Vehicle<\/code> object (line 12). The subclass constructor function was initialized referring to its properties from parent class and an additional <code>electric<\/code> variable (line 13). Properties from <code>Vehicle<\/code> (parent class) were referred using <code>super<\/code> keyword (line 14). The added <code>electric<\/code> variable added to the <code>HybridVehicle<\/code> subclass instance was defined using <code>this.electric = electric<\/code> (line 15).<\/p>\n<h3>Super Class Calls with <code>Super<\/code><\/h3>\n<p>The <strong>super<\/strong> keyword is used to access and call functions on an object&#8217;s parent. When used in a constructor, the super keyword appears alone and must be used before the this keyword is used. The\u00a0super\u00a0keyword can also be used to call functions on a parent object.<br \/>\nThe <code>super<\/code> keyword can be used to call methods from subclass (or parent class).<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/ Vehicle is a base class\nclass Vehicle {\n    constructor (make, model, year, fuel) {\n        this.make = make;\n        this.model = model;\n        this.year = year;\n        this.fuel = fuel;\n    }\n    toString () {\n        return `${this.make} | ${this.model} ${this.year} ${this.fuel}`\n    }\n\/\/ initialize method\n    reminder () {\n      console.log( this.toString() );\n    }\n}\n\/\/ HybridVehicle is a derived class\nclass HybridVehicle extends Vehicle {\n    constructor (make, model, year) {\n        super(make, model, year, &#039;hybrid&#039;);\n    }\n\/\/initialize method\n    reminder () {\n        super.reminder(); \n        console.log(`Would you look at that -- ${this.make} has hybrid!`);\n    }\n}\n\/\/create new MyHybrid instance\nconst myHybrid = new HybridVehicle(&#039;Toyota&#039;, &#039;Camry&#039;, 2018);\n\n\/\/access\nmyHybrid.reminder(); \n\/\/OUTPUT\nToyota | Camry 2018 hybrid\nWould you look at that -- Toyota has hybrid!<\/code><\/pre>\n<p>In the example above, we call <code>reminder()<\/code> method (line )from parent class <code>Vehicle<\/code> (line ) using super keyword on <code>HybridVehicle<\/code> subclass (a child class)<\/p>\n<h4>Symbol &amp; Mix-ins<\/h4>\n<p>The <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes\" target=\"_blank\" rel=\"noopener\">MDN Documentation<\/a> describes two additional methods <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Symbol\" target=\"_blank\" rel=\"noopener\">Symbol<\/a> (or <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Species\" target=\"_blank\" rel=\"noopener\">Species<\/a>) and <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes#Mix-ins\" target=\"_blank\" rel=\"noopener\">Mix-ins<\/a>. These topics are important in deep diving JS class, however discussion of these advance topic is outside the scope of this basic JS class learning-post. These topics will be revisited as in a separate learning-note post.<\/p>\n<h5>Wrapping Up<\/h5>\n<p>In this learning-note, we covered classes (declaration),sub classing with extends, super class calls with super, symbol methods . How classes map to prototype-based code??<\/p>\n<p>NEXT: <a href=\"https:\/\/tinjurewp.com\/jsblog\/understanding-javascript-class-prototypes\/\" target=\"_blank\" rel=\"noopener\">Understanding JavaScript Class &amp; Prototypes<\/a><\/p>\n<h5>Useful Resources &amp; Links<\/h5>\n<p>While preparing this post, I have referred the following references extensively. Visit original link for more information.<\/p>\n<ul>\n<li><a href=\"https:\/\/scotch.io\/tutorials\/better-javascript-with-es6-pt-ii-a-deep-dive-into-classes\" target=\"_blank\" rel=\"noopener\">Better JavaScript with ES6, Pt. II: A Deep Dive into Classes<\/a> &#8211; by <a href=\"https:\/\/scotch.io\/@PelekeS\" target=\"_blank\" rel=\"noopener\"><em>Peleke Sengstacke<\/em><\/a> | <a href=\"https:\/\/scotch.io\/\" target=\"_blank\" rel=\"noopener\">Scotch<\/a><\/li>\n<li><a href=\"http:\/\/exploringjs.com\/es6\/ch_classes.html\">Exploring ES6: Classes<\/a>&#8211; by <a href=\"http:\/\/2ality.com\/\" target=\"_blank\" rel=\"noopener\">Dr Axel Rauschmayer<\/a><\/li>\n<li><a href=\"https:\/\/scotch.io\/tutorials\/demystifying-es6-classes-and-prototypal-inheritance\" target=\"_blank\" rel=\"noopener\">Demystifying ES6 Classes And Prototypal Inheritance<\/a> &#8211; by <em>Neo Ighodaro<\/em> | <a href=\"https:\/\/scotch.io\/\" target=\"_blank\" rel=\"noopener\">Scotch<\/a><\/li>\n<li><a href=\"https:\/\/medium.com\/@naveenkarippai\/debunking-fake-classes-in-javascript-78f67a6b5c96\" target=\"_blank\" rel=\"noopener\">Debunking \u201cfake\u201d classes in JavaScript<\/a> &#8211; by <em>Naveen Karippai<\/em> | <a href=\"https:\/\/medium.com\/\" target=\"_blank\" rel=\"noopener\">Medium<\/a><\/li>\n<li><a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/understanding-classes-in-javascript\" target=\"_blank\" rel=\"noopener\">Understanding Classes in JavaScript<\/a> &#8211; by <a href=\"https:\/\/www.taniarascia.com\/\" target=\"_blank\" rel=\"noopener\"><em>Tania Rascia<\/em><\/a> | <a href=\"https:\/\/www.digitalocean.com\/community\/tutorial_series\/how-to-code-in-javascript\" target=\"_blank\" rel=\"noopener\">DigitalOcean<\/a><\/li>\n<li><a href=\"https:\/\/javascript.info\/object-oriented-programming\" target=\"_blank\" rel=\"noopener\">Objects, classes, inheritance<\/a> | <a href=\"https:\/\/javascript.info\/\" target=\"_blank\" rel=\"noopener\">The Modern JavaScript Tutorial<\/a><\/li>\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes\" target=\"_blank\" rel=\"noopener\">Classes<\/a> |<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\" target=\"_blank\" rel=\"noopener\"> MDN Documentation<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Note: This post is work-in-progress learning-note and still in active development and updated regularly. JavaScript is a Object Oriented language. Unlike other language (eg. C++, Java, Python etc) JS is not class-based nevertheless\u00a0 Objects in JavaScript are considered everything. In ES2015 (ES6), a prototype-based class keyword was introduced. In this learning note we will deep [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[46,4],"tags":[],"class_list":["post-4716","post","type-post","status-publish","format-standard","hentry","category-class","category-javascript"],"_links":{"self":[{"href":"https:\/\/learncode.tinjurewp.com\/wp-json\/wp\/v2\/posts\/4716","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learncode.tinjurewp.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learncode.tinjurewp.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learncode.tinjurewp.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/learncode.tinjurewp.com\/wp-json\/wp\/v2\/comments?post=4716"}],"version-history":[{"count":0,"href":"https:\/\/learncode.tinjurewp.com\/wp-json\/wp\/v2\/posts\/4716\/revisions"}],"wp:attachment":[{"href":"https:\/\/learncode.tinjurewp.com\/wp-json\/wp\/v2\/media?parent=4716"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learncode.tinjurewp.com\/wp-json\/wp\/v2\/categories?post=4716"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learncode.tinjurewp.com\/wp-json\/wp\/v2\/tags?post=4716"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}