Developers Club geek daily blog

1 year, 1 month ago
JavaScript, probably, the most known multiparadigmenny language in which there are a lot of unevident features. But whether nevertheless we love it or we abuse, the fact remains is the main language at which modern web works.

In the left year, there was an ECMAScript 2015 standard (informally ES6) which strongly changed what we got used to. There was a mass of new opportunities which in fact represent a modern superset of the language trying to solve the existing problems. Class, let, const, pointer functions … the developer who did not see the code written on ES6 not at once earlier will guess that before it, in fact, old kind JS.

There is a mass of the fine articles devoted to the modern standard. In the same post I want to show that modern JS when it is necessary to solve an essential problem can offer us. For example, to congratulate all on New Year.

Imperative approach


The simplest solution to make everything it is imperative. Yes, it is valid if to follow the principle "less more — more less", then it will be the most pragmatic solution:

function sayHappyNewYear(year){
    console.log('Happy New ' + year + ' Year!');
}
    
sayHappyNewYear(2016);


The solution is simple, and it will work in all environments where there is implementation of object of console, but in it there is a defect: we have not only a New Year, but also a set of other holidays. To create for every holiday the separate function not really reasonable occupation. If we need to format messages it is uniform, then at change of a format of the message it will be necessary to change the corresponding code in all functions (yes, examples in article turned out a little artificial). It is possible to take out, of course, everything that is connected with formatting, in the separate formatMessage function () and to pass through it a congratulation in all functions. But let's for a start try to reflect data domain by means of OOP and to look, than we can be helped by JavaScript with this situation.

Object-oriented approach


As all of you know well it is possible to write to JS in object-oriented style with inheritance based on prototypes:

function Greeter() {}

Greeter.prototype.doGreeting = function(msg) {
    console.log(msg);
}

function NewYearGreeter(currentYear) {
    this.currentYear = currentYear;
}

NewYearGreeter.prototype = Object.create(Greeter.prototype);
NewYearGreeter.prototype.constructor = NewYearGreeter;

NewYearGreeter.prototype.doGreeting = function() {
    var year = this.currentYear + 1;
    var newYearMsg = 'Happy New ' + year + ' Year!';
    Greeter.prototype.doGreeting.call(this, newYearMsg);
}

var newYearGreeter = new NewYearGreeter(2015);
newYearGreeter.doGreeting();


Quite verbose solution which plus that this code will work in all modern runtime-environments turned out (browsers, Node.js). Classes which are familiar to any programmer owning C ++, Java, C#, Python etc appeared from behind verboseness of implementation of the object-oriented approach in ES6. Here will look thus the example higher if to use the classes ES6:

'use strict';

class Greeter {
    doGreeting(msg) {
        console.log(msg);
    }
}

class NewYearGreeter extends Greeter {
    constructor(currentYear) {
        super();
        this.currentYear = currentYear;
    }

    doGreeting() {
        let year = this.currentYear + 1;
        let newYearMsg = 'Happy New ' + year + ' Year!';
        super.doGreeting(newYearMsg);
    }
}

let newYearGreeter = new NewYearGreeter(2015);
newYearGreeter.doGreeting();


Looks already more nice. But as you probably know there were many disputes around classes in JS. There were ardent opponents of this innovation. In general their position was clear — OOP in the long term generates a problem "a gorilla and banana":

The problem of object-oriented languages is that they drag with themselves all the implicit environment. You needed banana – and you receive a gorilla with banana, and the whole jungle in addition.
Joe Armstrong "Coders at Work"

Therefore language means which did possible creation of difficult taxonomy of classes by an easy way it was perceived by a warring party in bayonets. Anyway classes it is a language standard now, use, but without fanaticism.

It is good if inheritance generates a problem of connectivity what alternative option is? Composition.

Prefer object composition to class inheritance
Gamma, Helm, Johnson, Vlissids "Object-oriented design acceptances. Design patterns."

In JS, composition it is possible to implement by different methods. Here one of solutions which will work in all modern runtime-environments:

function extend(destination, source) {
    for (var key in source) {
        if (source.hasOwnProperty(key)) {
            destination[key] = source[key];
        }
    }
}

function Greeter() {
    this.doGreeting = function(msg) {
        console.log(msg);
    }
}

function NewYearGreeter(year) {
    this.year = year;

    this.doNewYearGreeting = function() {
        var newYearMsg = 'Happy New ' + this.year + ' Year!';
        this.doGreeting(newYearMsg);
    }
}

var greeter = new Greeter;
var newYearGreeter = new NewYearGreeter(2016);
extend(newYearGreeter, greeter);

newYearGreeter.doNewYearGreeting();


In this example by means of designers objects which properties (methods) are arranged in one entity (object of newYearGreeter) by means of the office extend function are created. The modern standard allows to simplify implementation of composition by means of Object.assign ():

'use strict';
let greeter = {
    doGreeting(msg) {
        console.log(msg);
    }
};

let newYearGreeter = {
    setYear(year) {
        this.year = year;
    },

    doNewYearGreeting() {
        let newYearMsg = 'Happy New ' + this.year + ' Year!';
        this.doGreeting(newYearMsg);
    }
};

Object.assign(newYearGreeter, greeter);
newYearGreeter.setYear(2016);

newYearGreeter.doNewYearGreeting();


Object.assign () in fact does most too, as extend, behind that exception that it can be used "from a box" at the same time can arrange any amount of objects.

It is the object party of a question. But JS also provides means for programming in functional style.

Functional style


Feature of such approach is that we do not operate with objects any more, and we operate with pure functions which composition allows to solve an objective. Our example too small therefore for an example we will take other concept from functional programming — a karrirovaniye:

function createGreeter(msg) {
    return function(param) {
        return msg.replace(/%.*%/, param);
    }
}

var greetWithNewYear = createGreeter('Happy New %year% Year!');
console.log(greetWithNewYear(2016));


In ES6 from means for simplification of programming in functional style, the most noticeable innovation — pointer functions. Pointer function is an anonymous function (for example, function right after return from an example is higher) or lambda expression as tells the people from functional camp. Here thus our example will be transformed if we use "a thick arrow":

function createGreeter(msg) {
    return param => msg.replace(/%.*%/, param);
}

var greetWithNewYear = createGreeter('Happy New %year% Year!');
console.log(greetWithNewYear(2016));


Programming in functional style gives many benefits: the code turns out more compact without ghost effects, but to it, of course, it is necessary to get used as at functional programming of a reasoning from the imperative level (how to make) move to a declarative level (what to make).

What to esteem / look?


Axel Raushmayer's blog:

A series of the articles ES6 in Depth on mozilla.org:

Youtube-channel Matthias Yokhonson:


Results


JavaScript develops very quickly — future standard prepares other remarkable innovations in language, but what we can use for creation of web applications already today by and large new incarnation of language, which purpose to simplify life to all developers.

(_ => ++_)(2015);

This article is a translation of the original post at habrahabr.ru/post/274415/
If you have any questions regarding the material covered in the article above, please, contact the original author of the post.
If you have any complaints about this article or you want this article to be deleted, please, drop an email here: sysmagazine.com@gmail.com.

We believe that the knowledge, which is available at the most popular Russian IT blog habrahabr.ru, should be accessed by everyone, even though it is poorly translated.
Shared knowledge makes the world better.
Best wishes.

comments powered by Disqus