Giter Site home page Giter Site logo

ws_objects's Introduction

Object-oriented JavaScript

In this set of staged examples we show how we can use objects to structure our data and write better, more maintainable code.

Stage 0: A basic program

  • index.html is a short web page that contains just a heading and an empty canvas. This page does not change throughout the stages.
  • index.js is a program that draws a crimson rectangle on the canvas. The properties of the rectangle are held in five variables.
  • See it.

Stage 1: A second rectangle (see the diff)

  • In this stage we add a steel-blue rectangle.
  • If we wanted to add more rectangles this would get repetitive and laboured.
  • There is repetition in both the implicit structure of the variables for each rectangle, and the code to draw the rectangles.
  • See it.

Stage 2: A drawRect function (see the diff)

  • We simplify the program by creating a drawRect function, so that the repetition when drawing rectangles is removed. We can now change the way all rectangles are drawn by changing this one function.
  • See it.

Stage 3: Using objects (see the diff)

  • We group the rectangle properties in objects, to structure the code better.
  • This allows us to simplify the property names.
  • The drawRect function now takes just two parameters.
  • See it.

Stage 4: Data encapsulation (see the diff)

  • The two rectangles in previous stages are similar; informally we might describe them as instances of the same class of objects, which we can name rectangle.
    • In programming language terms, we can define a Class which formalises the structure of our objects.
  • Here we create a Rectangle class.
    • By convention class names begin with a capital letter and are singular (e.g. Rectangle, not Rectangles).
    • Classes have a constructor function that is called when a new instance of the class is created.
    • Classes provide a standardised way of ensuring that every object has the same basic properties, and constructors set their initial values.
  • Each rectangle object (i.e. each instance of the Rectangle class) is now created using a single line of code.
  • See it.

Stage 5: Function encapsulation (see the diff)

  • The drawRect function is specific to rectangles, so it can become part of the Rectangle object.
    • In object-oriented terminology:
      • Functions inside classes are known as methods.
      • Methods are invoked (not called) on objects.
      • When a method is invoked, the object on which it was called can be accessed through a special variable named this.
  • Once the Rectangle class includes a draw function, each instance of rectangle can be asked to draw itself.
  • See it.

Stage 6: A Circle (see the diff)

  • We add a Circle class to complement our Rectangle.
  • Like rectangles, circles have x & y positions and a colour, but no width or height: instead they have a radius r.
  • The draw function is rewritten so that instances of Circle can draw themselves.
  • Now we can create and draw two circles.
  • See it.

Stage 7: Superclasses and subclasses (see the diff)

  • In the previous stage, there is some duplication in the properties (x, y and col).
  • We refactor the Rectangle and Circle classes, taking their common properties and moving them to a new class called Shape.
    • Rectangle and Circle are now subclasses of the Shape superclass.
    • The Shape class contains properties that are common to all shapes.
    • Rectangle and Circle only contain code specific to their particular shape.
    • The process of refactoring classes to create a new superclass is called generalisation.
  • Notice that in the constructor of a subclass, its superclass constructor is called using the super() function – this reduces duplication of code.
  • See it.

Stage 8: A file for classes (see the diff)

  • When code gets longer, often it's a good idea to modularise by moving independent pieces into separate files:
    • Here, we can move the class definitions into classes.mjs.
    • The .mjs extension is a convention used for JavaScript modules.
  • JavaScript modules export functions and variables. The import keyword is used to make these available in other files.
    • The script element in index.html must specify that type=module – only then are import and export allowed.
    • For security reasons, module imports are not allowed to load local files, therefore we need to look at this example through a web server; npm start will run a local web server on your machine.
  • See it.

Stage 9: An array of shapes (see the diff)

  • We are currently drawing four shapes. In the preceding stages, we stored them in four different variables. We treat them as a bag of shapes so it is better to use an array.
  • The items in the array can be accessed in a loop, which reduces the need to call draw multiple times.
  • The classes.mjs file has not changed at this stage.
    • This shows the benefit of modularization: when changing the way we store the shapes we did not need to see how they are implemented.
    • Not having the code in our editor means we cannot accidentally break it.
  • See it.

Stage 10: Inheriting functions from superclasses (see the diff)

  • A function that's defined in a superclass is inherited by all classes that extend the superclass.
  • We define a moveBy function that accepts two parameters (x & y) and adds these to the existing x and y properties of the instance.
  • We use this method to move all shapes to the right and down, then draw them a second time.
  • See it.

Stage 11: Getters and Setters (and underscores) (see the diff)

  • Getters and setters:
    • are a special type of method, invoked when a property is read or written.
    • are defined with the keyword get or set before the method name.
    • are used as if they were properties:
      • when we read the value of the property, the getter is invoked, and we receive its return value.
      • when we write into a property, the setter is invoked and receives, as its parameter, the value we wanted to set.
    • are often used to access internal properties, so there is a convention of starting internal property names with an underscore character and the rest of the name the same.
  • Here we add a getter & setter for the x property, whose value is internally stored in the _x property.
    • Inside the setter, we check the given value is a number.
  • In index.js, we set the x property of every shape to 50 – the setter gets invoked to do this.
  • See it.

Stage 12: Getters for computed properties (see the diff)

  • Here we add a getter for a new property: area
    • This is not a normal property where we store a value, instead it's a computed property whose value depends on other properties.
  • In Shape we define a getter for area that throws an error message, so if Shape is extended but the area method is not implemented, accessing area will give meaningful feedback.
  • In Rectangle and Circle we define area getter functions using appropriate formulae.
  • In index.js we can use the area getters as if they were properties on our shapes, logging the value to the console.
  • See it.

Stage 13: Private fields (Private properties) (see the diff)

  • The underscores seen previously are a common mechanism for programmers to informally communicate that a property is an implementation detail that is not intended for access or use by others.
  • JavaScript has the (experimental) ability to define private fields in classes.
    • Private fields are denoted by the hash symbol, used before the property name.
    • Private fields must all be declared before the constructor.
  • Private fields cannot be accessed from outside the object.
    • They are only accessible from methods defined within the class.
    • This means private fields cannot be accessed by subclasses, so getters/setters must be implemented if subclasses need read/write access.
  • In this stage, in classes.mjs we use private properties like #x and #y to hide properties that should be treated as implementation details.
  • See it.

ws_objects's People

Contributors

dependabot[bot] avatar ear1grey avatar jacekkopecky avatar

Watchers

 avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.