GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing en.wikibooks.org — JavaScript/Object-based programming - Wikibooks, open books for an open world
Object-oriented programming (OOP) is a software design paradigm that first arose in the 1960s and gained popularity in the 1990s. It strives for modularization, reusability, encapsulation and hiding of state (data) and behavior (functions), design in a hierarchy of generalization, inheritance, and more. It allows the components to be as modular as possible. In particular, when a new object type is created, it is expected that it should work without problems when placed in a different environment or new programming project. The benefits of this approach are a shorter development time and easier debugging because you're re-using program code that has already been proven. This 'black box' approach means that data goes into the object and other data comes out of the object, but what goes on inside isn't something you need to concern yourself with. Over time different techniques have been developed to implement OOP. The most popular ones are the class-based and the prototype-based approach. Class-based OOPClasses are a blueprint that defines all aspects - state as well as behavior - of a group of structurally identical objects. The blueprint is called the class, and the objects instances of that class. Popular members of the C-family languages, especially Java, C++, and C#, implement OOP with this class-based approach. Prototype-based OOPIn the prototype-based approach, every object stores its state and behavior. In addition, it has a prototype (or // define a constructor for the class "Class4Person" function Class4Person () { this.firstname = ""; this.lastname = ""; this.age = 0; return this; }; // define a method "setAge()" for the class "Class4Person" Class4Person.prototype.setAge = function (pYears) { // set age of person this.age = pYears; } // define a method "getOlder()" for the class "Class4Person" Class4Person.prototype.getOlder = function (pYears) { // if pYear parameter is not set, define pYears=1 pYears = pYears || 1; // increment age with pYears this.age += pYears; } // define a method "getInfo()" for the class "Class4Person" Class4Person.prototype.getInfo = function () { // create an info string about person return "My name is " + this.firstname + " " + this.lastname + " and I am " + this.age + " years old." } // create instance of Class4Person let anna = new Class4Person(); // set attributes of instance "anna" anna.firstname = "Anna"; anna.lastname = "Miller"; // call methods of instance "anna" anna.setAge(15); // anna.age = 15 anna.getOlder(5); // anna.age = 20 anna.getOlder(); // anna.age = 21 // create instance of Class4Person let bert = new Class4Person(); // set attributes of instance "bert" bert.firstname = "Bert"; bert.lastname = "Smith"; // call method for instance "bert" bert.set_age(30); // age of instance "bert" is now set to 30 - bert.age = 30 // create info string for instances and show in console log console.log(anna.getInfo()); // "I am Anna Miller and I am 21 years old." console.log(bert.getInfo()); // "I am Bert Smith and I am 30 years old." OOP in JavaScript "Two jackets for one body"One of JavaScript's cornerstones is the provision of objects in accordance with the rules of the prototype-based OOP. Objects consist of properties that are key/value pairs holding data as well as methods. One of those properties is always the prototype property '__proto__'. It points to the 'parent' object and, by this, realizes the relationship.
// relationships are realized by the property '__proto__' let parent = []; let child = { name: "Joel", __proto__: parent, }; console.log(Object.getPrototypeOf(child)); // Array [] ┌─────────────────────┐ ┌─────────────────────┐ │ child │ ┌──> │ parent │ ├─────────────────────┤ | ├─────────────────────┤ │ name: Joel │ | │ .... : ... │ ├─────────────────────┤ | ├─────────────────────┤ │ __proto__: parent │ ──┘ │ __proto__: ... │ ──> ... ──> null └─────────────────────┘ └─────────────────────┘ If a requested property is missed on any object, the JavaScript engine searches it in the 'parent' object, 'grandparent' object, and so on. This is called the prototype chain. All of that applies to user-defined objects and system-defined objects like Since EcmaScript 2015 (ES6), the syntax offers keywords like In summary, the syntax of JavaScript offers two ways to express object-oriented features like inheritance in the source code: the 'classical' and the 'class' style. Despite the different syntax, the implementation techniques differ only slightly. The classical syntaxSince its first days, JavaScript has defined the parent/child relation of objects with the 'prototype' mechanism. If not explicitly notated in the source code, this happens automatically. The classical syntax exposes it quite well. To define a parent/child relation of two objects explicitly, you should use the method <!DOCTYPE html> <html> <head> <script> function go() { "use strict"; const adult = { familyName: "McAlister", showFamily: function() {return "The family name is: " + this.familyName;} }; const child = { firstName: "Joel", kindergarten: "House of Dwars" }; // 'familyName' and 'showFamily()' are undefined here! alert(child.firstName + " " + child.familyName); // set the intended prototype chain Object.setPrototypeOf(child, adult); // or: child.__proto__ = adult; alert(child.firstName + " " + child.familyName); alert(child.showFamily()); } </script> </head> <body id="body"> <button onclick="go()">Run the demo</button> </body> </html> The 'adult' object contains the 'familyName' and a function 'showFamily'. In the first step, they are not known in the object 'child'. After The next script demonstrates the prototype chain. It starts with the user-defined variables function go() {
"use strict";
// define an array with three elements
const myArray = [0, 1, 2];
let theObject = myArray;
do {
// show the object's prototype
console.log(Object.getPrototypeOf(theObject)); // Array[], Object{...}, null
// or: console.log(theObject.__proto__);
// switch to the next higher level
theObject = Object.getPrototypeOf(theObject);
} while (theObject);
}
As you know, properties are key/value pairs. Hence it is possible to directly use the value of the 'prototype' property to identify and manipulate prototypes. Interestingly the key's name isn't 'prototype' but '__proto__'. This is shown in line 11. Nevertheless, we recommend ignoring this technique and using API methods for prototype manipulations, such as The 'class' syntaxThe script defines two classes, Adult and Child with some internal properties, one of them being a method. The keyword <!DOCTYPE html> <html> <head> <script> function go() { "use strict"; class Adult { constructor(familyName) { this.familyName = familyName; } showFamily() {return "The family name is: " + this.familyName;} } class Child extends Adult { constructor(firstName, familyName, kindergarten) { super(familyName); this.firstName = firstName; this.kindergarten = kindergarten; } } const joel = new Child("Joel", "McAlister", "House of Dwars"); alert(joel.firstName + " " + joel.familyName); alert(joel.showFamily()); } </script> </head> <body id="body"> <button onclick="go()">Run the demo</button> </body> </html> The property Please note again that this class-based inheritance in JavaScript is implemented on top of the prototype-based classical approach. See also |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |