Unlike other object-oriented languages, it is possible in JavaScript to add or to remove properties after an object has been created
delete keyword can be used to delete an object’s property (it will become undefined)
// empty object with properties/methodsvar darkVador = {};// add properties after darkVador has been createddarkVador.race = 'human';darkVador.job = 'villain';// add some methodsdarkVador.talk = function() { return 'come to the dark side, Luke!' + this.breathe();};// delete propertydelete darkVador.race;
this keyword
The key thing to remember is that it is bound to the calling object when the function is called, not when the function is created.
Classes
Before 2015, in JavaScript 5 (also called ES5), we did not have such a concept, instead we had “constructor functions”.
In modern JavaScript (after 2015), we have the concept of classes, and the syntax is rather similar to what we find in other object oriented programming languages.
new keyword
The new keyword does the following:
When a function is used as a constructor (with the new keyword), its this is bound to the new object being constructed
The function body executes. Usually it modifies this, adds new properties to it.
The value of this is returned.
If return is called with an object, then the object is returned instead of this.
If return is called with a primitive, it’s ignored.
Creating JS Objects
Objects can be created using object literal, new Function, or class
1. Object literal
var obj = { age: 30, name: KK}
2. ES5 syntax
Any function in JavaScript can act as a constructor when the function is invoked with new operator.
We need to adhere to following conventions to distinguish class from regular objects
Function name starts with capital letter using function keyword
The parameters have the same name as the properties they correspond to (name, side)
We use the this keyword to distinguish the property and the parameter
The context of this changes in different scenarios, In case of when function is called with new operator, this becomes the newly created object.
function Hero(name, side) { this.name = name; // code outside of methods is usually for initializing this.side = side; // the properties. Very often, they match the parameters this.speak = function() { return "<p>My name is " + this.name + ", I'm with the " + this.side + ".</p>"; }}var darkVador = new Hero("Dark Vador", "empire");
Note: JS does not support constructor overloading. If you want to implement you need to use args spread syntax
3. ES6 syntax
keywords used: class, constructor
No need to use function
class Hero { constructor(name, side) { this.name = name; // property this.side = side; // property } speak() { // method, no more "function" return "<p>My name is " + this.name + ", I'm with the " + this.side + ".</p>"; }}var darkVador = new Hero("Dark Vador", "empire");
Static properties and methods
Static methods:
created with static keyword
Static properties:
created outside class declaration in ES6
With latest JS version, can be created with static keyword inside class
class Point { constructor(x, y) { this.x = x; this.y = y; // static property Point.nbPointsCreated++; } // static method static distance(a, b) { const dx = a.x - b.x; const dy = a.y - b.y; return Math.sqrt(dx*dx + dy*dy); }}// static propertyPoint.nbPointsCreated=0;// We create 3 pointsconst p1 = new Point(5, 5);const p2 = new Point(10, 10);console.log(Point.distance(p1, p2)); // static methodcosole.log(Point.nbPointsCreated); // static property
Getters and Setters
get and set keywords are used to define getters and setters
getters and setters are useful for processing properties, doing checks, changing them before returning their value, etc.
The function name must match the property name for getter/setter
implicit properties are by convention prefixed by underscore _
class Person { constructor(givenName, familyName) { this.givenName = givenName; // "normal name" this._familyName = familyName; // starts with "_" } // having "get familyName" is equivalent to declaring a property // named "familyName", but in this case we have to use ANOTHER // name for the variable that will be used to store the property // value. A convention is to keep the same name but add an // underscore at the beginning. // Ex: get name(n) { this._name = n;} get familyName() { return this._familyName.toUpperCase(); } set familyName(newName) { // validation could be checked here such as // only allowing non numerical values this._familyName = newName; } walk() { return (this.givenName + ' ' + this._familyName + ' is walking.'); }}let p1 = new Person('Michel', 'Buffa');console.log(p1.familyName); // will display BUFFA in the devtool consolep1.familyName = 'Smith'; // this will call implicitly set