Javascript Practices
Jul-2022
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