Jump to content

JavaScript/OOP-classes

From Wikibooks, open books for an open world



The popularity of class-based programming languages inspires the JavaScript community to cover its prototype-based implementation of OOP with a syntax that mimics a class-based approach. EcmaScript 2015 (ES6) gets expanded by corresponding key words like 'class' or 'extend'.

Classes are templates or 'blueprints' to create objects. They encapsulate their data and contain functions to work on it.

Creation

[edit | edit source]
classPerson{// Class body is always implicitly in "use strict" modeconstructor(name){// Data. Declarations like 'let x = 0' are not necessary.this.name=name;}// functionalityshowName(){return"My name is: "+this.name;}}constada=newPerson("Lovelace");alert(ada.showName());

The keyword class introduces the class definition. In the example, Person is the class name. It is followed by the class body that is enclosed in curly brackets { }, lines 1 - 11. Within the body, there is a special method constructor. This function is invoked during class creation. In the example, it takes one argument, the name of a person. Within constructor this argument is stored internally by using the keyword 'this'. The class offers only one functionality: the showName method.

Static properties and methods

[edit | edit source]

The above syntax shows how to handle properties and methods of individual objects (instances - like 'ada' in the above example). It's also possible to define properties and methods that are not available at the level of individual objects but at the class level - 'Person' in the above example. They are introduced by the keyword static.

classPerson{constructor(name){// datathis.name=name;}staticclassName="The PERSON Class";staticshowClassName(){return"The name of this class is: "+this.className};showName(){return"My name is: "+this.name;}}constada=newPerson("Lovelace");// alert(ada.showClassName()); // Error!alert(Person.showClassName());

Lines 7 and 8 use the 'static' keyword. Therefore the property and method are NOT available for instances, only for the class altogether.

Class methods can be offered as properties. This frees the programmer to distinguish between access to methods - via parenthesis () - and properties. The keyword get introduces the feature.

classPerson{constructor(name){this.name=name;}// gettergetshowTheName(){returnthis.showName();}// 'regular' methodshowName(){return"My name is: "+this.name;}}constada=newPerson("Lovelace");// NO parenthesis ()alert(ada.showTheName);

Inheritance

[edit | edit source]

Next, we define a hierarchy of classes. This is done with the keyword extends. In the example, Employee is a sub-class of Person and has access to all its properties and methods.

classPerson{constructor(name){this.name=name;}// methodshowName(){return"My name is: "+this.name;}}classEmployeeextendsPerson{constructor(name,company){super(name);this.company=company;}// methodshowCompany(){return"I, "+this.name+", work at the company "+this.company;}}consthenry=newEmployee("Henry Miller","ACME Inc.");alert(henry.showCompany());alert(henry.showName());// method of the parent class

Line 12 invokes the constructor of the parent class. This is necessary because the parent's constructor creates 'this'.

Access control

[edit | edit source]

By default, class properties and methods are accessible. You can hide them by using a hash # as the first character of their name.

classPerson{// two hidden properties (sometimes called 'private fields')#firstName;#lastName;constructor(firstName,lastName){this.#firstName=firstName;this.#lastName=lastName;// one public propertythis.name=lastName+", "+firstName;}#showName(){// hidden methodalert("My name is "+this.name);}}constada=newPerson("Ada","Lovelace");alert(ada.name);// okalert(ada.firstName);// undefinedalert(ada.#firstName);// undeclared private fieldalert(ada.#showName());// undeclared private method

Polymorphism

[edit | edit source]

If a method name is used in a 'parent' class as well as in a 'child' class, the JavaScript engine invokes that one of the correlating class.

classPerson{constructor(name){this.name=name;}// method name is used also in 'child'showName(){return"My name is: "+this.name;}}classEmployeeextendsPerson{constructor(name,company){super(name);this.company=company;}// same method name as in 'parent'showName(){return"My name is: "+this.name+". I'm working at the company "+this.company;}}consthenry=newEmployee("Henry Miller","ACME Inc.");alert(henry.showName());// from EmployeeconstnextPerson=newPerson("John");alert(nextPerson.showName());// from Person

The example defines and uses two different methods showName.

this is not a variable or an object; it's a keyword. Depending on the context, it refers to different things. In the context of class definitions, it refers to the class itself, e.g., this.city = "Nairobi" refers to the property 'city' of the current class.

When this is used at the top level of a file (in other words: outside of any function or object), it refers to the global object. In a function, in strict mode, this is undefined. In a DOM event, it refers to the element that received the event.

Exercises

[edit | edit source]
... are available on another page (click here).

See also

[edit | edit source]
close