JS classes

by Kiril Knysh

What is class?

Class is a schema

What is object?

Object is a `real` instance of schema

What is object?

unordered dynamic collection of properties (key-value pairs)

  • key - unique (in scope of object) string
  • value - primitive, object, function

What is object?

Everything is an object


var obj = { prop0: 0 };
obj.prop1 = 1;

var func = function() {};
func.prop1 = 1;

var arr = [1, 2, 4];
arr.prop1 = 1;
						

Classes in JS

  • object literals (not really classes)
  • functions (more like classes but still not)
  • ES2015 classes

Classes in JS object literals


function legoMan(name) {
    return {
        name: name,
        say: function(message) {
            console.log(this.name + ': "' + message + '"');
        }
    };
}
						

var alex = legoMan('Alex');
alex.say('Hello, Kattie!'); // Alex: "Hello, Kattie!"

var kattie = legoMan('Kattie');
kattie.say('No'); // Kattie: "No"
						

Classes in JS (bad) functions


function LegoMan(name) {
    this.name = name;
    this.say = function(message) {
        console.log(this.name + ': "' + message + '"');
    }
}
						

var alex = new LegoMan('Alex');
alex.say('Hello, Kattie!'); // Alex: "Hello, Kattie!"

var kattie = new LegoMan('Kattie');
kattie.say('No'); // Kattie: "No"
						

Classes in JS (good) functions


function LegoMan(name) {
    this.name = name;
}

LegoMan.prototype.say = function(message) {
    console.log(this.name + ': "' + message + '"');
}
						

var alex = new LegoMan('Alex');
alex.say('Hello, Kattie!'); // Alex: "Hello, Kattie!"

var kattie = new LegoMan('Kattie');
kattie.say('No'); // Kattie: "No"
						

Classes in JS functions

What is prototype?

  • technically - a regular JS object
  • property of every function
  • created by JS environment

Classes in JS functions

[[Prototype]]

  • technically - a regular object
  • property of every object
  • accessible via __proto__

Classes in JS functions


function LegoMan(name) {
    this.name = name;
}

LegoMan.prototype.say = function(message) {
    console.log(this.name + ': "' + message + '"');
}

var alex = new LegoMan('Alex');

Classes in JS ES2015 classes


class LegoMan {
    constructor(name) {
        this.name = name;
    }

    say(message) {
        console.log(this.name + ': "' + message + '"');
    }
}
						

const alex = new LegoMan('Alex');
alex.say('Hello, Kattie!'); // Alex: "Hello, Kattie!"

const kattie = new LegoMan('Kattie');
kattie.say('Hello!'); // Kattie: "Hello!"
						

Classes in JS ES2015 classes


// TypeError: Class constructor LegoMan cannot be invoked without 'new'
const alex = LegoMan('Alex');
						

// SyntaxError: A class may only have one constructor
class LegoMan {
    constructor(name) { }

    constructor(name) { }
}
						

Classes in JS ES2015 classes


// ReferenceError: LegoMan is not defined
const alex = new LegoMan('Alex');
class LegoMan {
    constructor(name) {
        this.name = name;
    }
}
						

LegoMan.prototype.constructor === LegoMan; // true
						

Classes in JS ES2015 classes


class LegoMan {
    constructor(name) {
        this.name = name;
        this.age = 0;
    }

    set newAge(value) {
        this.age = value;
    }

    get represent() {
        return `My name is ${this.name}. I am ${this.age} years old.`;
    }
}
						

const alex = new LegoMan('Alex');
alex.represent // My name is Alex. I am 0 years old.
alex.newAge = 18;
alex.represent // My name is Alex. I am 18 years old.
						

Classes in JS ES2015 classes


class LegoMan {
    constructor(name) {
        this.name = name;
    }

    static getInfo(man) {
        return `This is ${man.name}.`;
    }
}
						

const alex = new LegoMan('Alex');
LegoMan.getInfo(alex); // This is Alex
alex.getInfo // undefined
						

typeof


typeof 132 // "number"
typeof 2.71 // "number"
typeof 'Alex' // "string"
typeof LegoMan // "function"
typeof true // "boolean"
typeof {} // "object""
					

typeof NaN // "number"
typeof new Number(132) // "object"
typeof [1, 2, 3] // "object", Array.isArray should be used
typeof null // "object"
					

instanceof


class LegoMan {
    constructor(name) {
        this.name = name;
    }
}

const alex = new LegoMan('Alex');
alex instanceof LegoMan // true
alex instanceof Object // true
					

alex instanceof LegoMan

LegoMan[@@hasInstance](alex)
					

Inheritance

Classical (C++, C#, Java)

  • classes inherit from classes
  • and create subclass relationships: hierarchical class taxonomies

Prototypal (Lua, JavaScript)

  • A prototype is a working object instance
  • Objects inherit directly from other objects

Inheritance

  • Crockford way
  • ES5 way
  • ES2015 way

Inheritance Crockford way


function extend(Child, Parent) {
    var F = function() { }
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    Child.superclass = Parent.prototype; // optional
}
					

Inheritance ES5 way


function extend(Child, Parent) {
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Child;
    Child.superclass = Parent.prototype; // optional
}
					    

Inheritance ES5 way


function extend(Child, Parent) {
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Child;
    Child.superclass = Parent.prototype; // optional
}

function LegoBatMan(name) {
    LegoBatMan.superclass.constructor.call(this, name);
}

extend(LegoBatMan, LegoMan);

Inheritance ES2015 way


class LegoBatMan extends LegoMan {
    constructor(name) {
        super(name);
    }

    say(message) {
        console.log('|\\__/|');
        super.say(message);
        console.log('|\\__/|');
    }
}
					    

const bruce = new LegoBatMan('Bruce');
bruce.say('this city needs a hero');
// |\__/|
// Bruce: "this city needs a hero"
// |\__/|
					    

Inheritance Be careful

Why classes are good?

  • help to define data structures
  • help to organize data relationships
  • modularity
  • extensibility

Why classes are bad?

  • may result in classes hell
  • a lot of time designing the code
  • may destroy "transparency" of logic
  • not flexible

PS

  • "favor composition over class inheritance" - GoF
  • "don’t inherit more than once" - Dan Abramov
  • "use your brain" - Dzmitry Varabei

Thanks