Do I need classes in JavaScript? part 2

  • Tutorial
see Part 1

Performance: creating classes through __proto__


image
In terms of performance, Object.create unfortunately does not give large results (especially with the second argument - descriptors). In contrast to using __proto__ directly, which turned out to be even faster than connecting the constructor function with the new operator - see jsPerf . I also note that the use of descriptors is not particularly convenient.

Clonejs nano


For the above reasons, create the clone function:
function clone(proto, properties){
    properties.__proto__ = proto;
    return properties;
}

Cloning

В прототип-ориентированных системах предоставляется два метода создания нового объекта: клонирование существующего объекта, либо создание объекта «с нуля». Для создания объекта с нуля программисту предоставляются синтаксические средства добавления свойств и методов в объект. В дальнейшем, с получившегося объекта может быть получена полная копия — клон. В процессе клонирования копия наследует все характеристики своего прототипа, но с этого момента она становится самостоятельной и может быть изменена.
© Wikipedia
A function clone() , as the name implies, creates clones of objects. A clone is a lazy shallow copy , that is, it is actually not a copy, but just a reference to the object, but if you add / replace any of its properties, this will not affect the parent object (prototype).
All objects in JavaScript are clones of Object.prototype (with the exception of itself and objects created with Object.create(null) ).

/// "Класс"
    var duck$ = {
        name: "Unnamed",
        quack: function(){
            console.log( this.name +" Duck: Quack-quack!");
        }
    };
/// Наследование
    var talkingDuck$ = clone( duck$, {
        quack: function(){
            duck$.quack.call(this);
            console.log("My name is "+ this.name +"!");
        }
    });
/// Инстанцирование
    var donald = clone( talkingDuck$, {name: "Donald"});

As an alternative, you can use the object-oriented option:

/// object$ – прототип всех наших объектов
var object$ = {
    clone: function(properties){
        properties.__proto__ = this;
        return properties;
};

/// "Класс"
    var duck$ = object$.clone({
        name: "Unnamed",
        quack: function(){
            console.log( this.name +" Duck: Quack-quack!");
        }
    };
/// Наследование
    var talkingDuck$ = duck$.clone({
        quack: function(){
            duck$.quack.call(this);
            console.log("My name is "+ this.name +"!");
        }
    });
/// Инстанцирование
    var donald = talkingDuck$.clone({name: "Donald"});

Compatibility


__proto__ is part of ECMA Script 6 , due to be approved in December 2013 .

It is fair to say that the clone function does not actually create any objects, but simply changes the object properties to its prototype. This can be easily fixed:
function clone(proto, properties){
    var newObj = {__proto__: proto};
    for(var key in properties) newObj[key] = properties[key];
    return newObj;
}

But then we will lose in productivity. It’s better to introduce a rule:
Использование второго аргумента после клонирования нежелательно, и возможно при использовании исключительно его собственных свойств.
This rule will also allow compatibility with Internet Explorer 6–10 and ECMA Script 3:
    function clone(/** Object */proto, /** ObjLiteral= */ownProperties){
        function Clone(ownProperties){
            for(var key in ownProperties) this[key] = ownProperties[key];
        };
        Clone.prototype = proto;
        
        return new Clone(ownProperties);
    }



This is how the clone.js framework was created .