ES6 of the Week

This Week's Episode:

class syntax

Class Syntax

What it is

What it isn't

  • syntactic sugar for writing constructor functions
  • familiar to developers coming from other languages
  • adding new functionality - behavior is the SAME as a constructor function
  • replacing prototypal inheritance somehow

Old dog...

function Dog (name, breed) {
    this.name = name;
    this.breed = breed;
}

// instance methods
Dog.prototype.bark = function () {
    console.log('arf!');
};
Dog.prototype.sayName = function () {
    console.log('Hi, my name is ', this.name); 
};

// static methods
Dog.fetchAll = function () {
    return $http.get('/api/dogs')
        .then(res => res.data)
	.catch(console.error);
};

const cooper = new Dog('Cooper', 'golden');
cooper.bark(); // arf!

...new tricks!

class Dog {
    constructor (name, breed) {
        this.name = name;
	this.breed = breed;
    }
	
    sayName () {
	console.log('Hi, my name is ', this.name);
    }
	
    bark () {
        console.log('arf!');
    }
	
    static fetchAll () {
        return $http.get('/api/dogs')
	    .then(res => res.data)
	    .catch(console.error);
    }
}

const cooper = new Dog('Cooper', 'golden');
cooper.bark(); // arf!

Constructor method

class Dog {
    constructor (name, breed) {
        this.name = name;
	this.breed = breed;
    }
	
    sayName () {
	console.log('Hi, my name is ', this.name);
    }
	
    bark () {
        console.log('arf!');
    }
	
    static fetchAll () {
        return $http.get('/api/dogs')
	    .then(res => res.data)
	    .catch(console.error);
    }
}

const cooper = new Dog('Cooper', 'golden');
cooper.bark(); // arf!

Static methods

class Dog {
    constructor (name, breed) {
        this.name = name;
	this.breed = breed;
    }
	
    sayName () {
	console.log('Hi, my name is ', this.name);
    }
	
    bark () {
        console.log('arf!');
    }
	
    static fetchAll () {
        return $http.get('/api/dogs')
	    .then(res => res.data)
	    .catch(console.error);
    }
}

const cooper = new Dog('Cooper', 'golden');
cooper.bark(); // arf!

Prototype methods

class Dog {
    constructor (name, breed) {
        this.name = name;
	this.breed = breed;
    }
	
    sayName () {
	console.log('Hi, my name is ', this.name);
    }
	
    bark () {
        console.log('arf!');
    }
	
    static fetchAll () {
        return $http.get('/api/dogs')
	    .then(res => res.data)
	    .catch(console.error);
    }
}

const cooper = new Dog('Cooper', 'golden');
cooper.bark(); // arf!

Look ma, no separators!

class MyClass {
    foo() {}
    ; // OK, ignored
    , // SyntaxError!!
    bar() {}
}

Getters & Setters

class Person {
    constructor(name) {
        this._name = name;
    }
  
    get name() {
        return this._name.toUpperCase();
    }
  
    set name(newName) {
        this._name = newName;   
        // validation could be checked here, like only allowing non-numerical values
    }
  
    walk() {
        console.log(this._name + ' is walking.');
    }
}
         
let bob = new Person('Bob');
console.log(bob.name);  // Outputs 'BOB'

class based inheritance

vs.

prototype based inheritance

Inheritance

  • Inheritance can be sort of a pain in JavaScript...

Old pattern

function Animal (name) {
    this.name = name;
}
Animal.prototype.sayName = function () {
    console.log('Hi, my name is ', this.name);
};

function Dog (name, breed) {
    Animal.call(this, name);
    this.breed = breed;
}
Dog.prototype.bark = function () {
    console.log('arf!');
};

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

"Super" inheritance

class Animal {
    constructor (name) {
        this.name = name;
    }
	
    sayName () {
	console.log('Hi, my name is ', this.name);
    }
}

class Dog extends Animal {
    constructor (name, breed) {
        super(name);
	this.breed = breed;
    }
	
    bark () {
        super.sayName();
	console.log('arf!');
    }
}

"Super" erroring

exports.NotFound = class NotFound extends Error {
  constructor() {
    super(...arguments);
    this.status = 404;
  }
}

exports.BadRequest = class BadRequest extends Error {
  constructor() {
    super(...arguments);
    this.status = 400;
  }
}

exports.UnauthorizedRequest = class UnauthorizedRequest extends Error {
  constructor() {
    super(...arguments);
    this.status = 401;
  }
}

Still constructor functions

class Dog {
    constructor (name, breed) {
        this.name = name;
	this.breed = breed;
    }
}

// totally fine!
Dog.prototype.sayName = function () { /** etc */ }

console.log(typeof Dog) // "function"

Hoisting...or nah

new Foo(); // ReferenceError

class Foo {}



function functionThatUsesBar() {
    new Bar();
}

functionThatUsesBar(); // ReferenceError
class Bar {}
functionThatUsesBar(); // OK

see you next week!

ES6 of the Week - 3 (class syntax)

By beelai88

ES6 of the Week - 3 (class syntax)

Class syntax

  • 570