Javascript Practices

DRAFT 🌱

Object-Oriented Programming in JS

Value Types

  • Primitives are copied by their value,
  • Objects are copied by their reference

Value Types: Number, String, Boolean, Symbol, undefined, null
Reference Types: Object, Function, Array

let number = 10;
function increase(number){
    number++;
}

increase(number); // 10

means number in the main scope is different the number in function\’s scope.

let obj = { value: 10 };
function increase(obj){
    obj.value++;
}

increase(obj); // 11

Classes

JavaScript actually doesn’t have Class concept exactly like in C++, but can be implemented in different ways with the same purpose.

Object Type Instantiation

Every time a circle needed same implementation repeats, means if an update requested on the model will be needed to applied to the instances.

let circleObject = {
  radius: 0,
  draw: function(){
    console.log("draw");
  }
}
// Usage
let circle1 = circleObject;
let circle2 = circleObject;
let circle3 = circleObject;

circle1.radius = 1;
circle2.radius = 5;
circle3.draw(); // draw

Factory Functions

Data instance identification with “behaviour”.

// Factory Function
function createCircle(radius){
  return { 
    radius, // we don't have to write like radius: radius (key: parameter)
    draw: function(){
      console.log("draw");
    }
  }
}
// Usage
let circle4 = createCircle(8);
circle4.draw(); // draw
circle4.radius = 12; // { radius: 3, draw: [Function: draw] }

Constructor Function

Starts with uppercase letter, closest way to Class concept in C and Java, but again it’s not actual class concept, it is a function instead.
new expression is must, if not used this inside function will point ot window or root object.

// Constructor Function
function Circle(radius){
    this.radius = radius;
    this.draw = function(){
        console.log("draw");
    }
}
// Usage 
let circle12 = new Circle(8); // creates Circle class object with 8 radius.
circle12.draw() // draw
circle12.radius = 9 // 9
circle12 // Circle { radius: 9, draw: [Function (anonymous)] }
// this is an actual object, not a function, look...
Circle.name // "Circle"
Circle.length // 1 arguments length

Advanced

Classes can get messy when not written in right way, since they are objects actually, their properties are public. if accidentally calls a method while intented to have a different logic, results might changing a property and not able to follow where and how.

In order to avoid risky way of definitions, it’s better to use local scoped variables instead of properties.

function Circle(radius) {
    this.radius = radius;
    // this.defaultLocation, instead :
    let defaultLocation = { x: 0, y: 0 };

    Object.defineProperty(this, 'defaultLocation', {
        get: function(){
            return defaultLocation;
        },
        set: function(value){
            if (!value.x || !value.y)
                throw new Error('Invalid location.');
            // set the new value  to the property safely
            defualtLocation = value;
        }
    });
}
// Usage
const circle = new Circle(10);
circle.defaultLocation = 1; // throws error cos' not entered all params, y is missing
circle.defaultLocation = {x:1, y:2} // { x: 1, y: 2 }

Example: Listen to Keyboard Entries

document.addEventListener('keyup', (e) => {    
        if (    
                e.code === 'KeyS' ||       
                e.code === "ArrowUp" ||      
                e.code === "NumpadDivide"    
        ) alert(`Clicked on: ${e.code}`);    
});    

Modules

Division of complex scripts by files.

Modules in NodeJS

NodeJS uses requireJS to manage moduling as default
exported.js file

module.exports = {
    incrementOf: function (n) {
        return n++;
    },
    decrementOf: function (n) {
        return n--;
    },
};

importing.js

const the = require('./exported');

console.log(the.incrementOf(99)); // 100
console.log(the.decrementOf(11)); // 10

Start the Discussion!Leave a Reply