Search code examples
javascriptoopprototypeecmascript-6django-class-based-views

Class-based and Object-based languages comparison (ECMAScript Specification)


In a class-based object-oriented language, in general, state is carried by instances, methods are carried by classes, and inheritance is only of structure and behaviour. In ECMAScript, the state and methods are carried by objects, while structure, behaviour, and state are all inherited.

This is the snippet from ECMAScript Specification June 2015. I don't understant parts of this text.

  • State is carried by instances - what does state mean in this context and example of this (c++ is preferred)
  • Methods are carried by classes - this probably means , that if I want to know object's methods , I need to look at the class of that object.
  • Inheritance is only of structure and behaviour - only structure and behaviour is inherited?
  • And so on...

Can anyone please explain this in details? examples would be great.


Solution

  • Okay, I'll take a shot at answering this question.

    Background on ECMAScript 6 classes as syntactic sugar

    ES6 classes are just syntactic sugar over the ordinary prototypal inheritance found in ECMAScript (aka JavaScript).

    class Foo {
        constructor(a, b) {
          this.c = a;
          this.d = b;
        }
    
        static bar() {}
    
        another() {}
    }
    

    This is equivalent to:

    function Foo(a, b) { 
      this.c = a; 
      this.d = b; 
    }
    
    Foo.bar = function() {};
    
    Foo.prototype = {
      another: function() {}
    };
    

    Doing inheritance in ES6 is a lot easier than the old method though:

    class Foo extends Bar {
        ...
    }
    

    Doing the same in ES5 or earlier is prone to issues, but that is slightly off-topic.

    Questions

    State is carried by instances - what does state mean in this context and example of this (c++ is preferred)

    An instance of a class is an object similar to C++.

    class Foo {
      constructor(a) {
        this.value = a;
      }
    
      getValue() {
        return this.value;
      }
    }
    
    var foo = new Foo(42);
    console.log(foo.getValue()); // prints 42
    

    Equivalent in C++:

    class Foo {
    private:
      int value;  
    public:
      Foo(int a) : value(a) {}
    
      int getValue() {
        return value;
      }
    };
    
    void main() {
      Foo foo = new Foo(42);
      std::cout << +foo.getValue() << std::endl;
    }
    

    As you can see, the instances of a class behave the same way in ES6 and C++, however there are no literal equivalents to private or public encapsulation in ES6.

    Methods are carried by classes - this probably means, that if I want to know object's methods, I need to look at the class of that object.

    In ECMAScript, you can override functions on an instance of a class, as it is just an object like everything else.

    var foo = new Foo(42);
    foo.getValue = function() { return this.value + 1; };
    console.log(foo.getValue()); // returns 43
    console.log(foo.constructor.prototype.getValue.call(foo)); // returns 42
    

    Using .constructor.prototype of an object gets the prototype of the object when it has been instantiated with the new keyword.

    Inheritance is only of structure and behaviour - only structure and behaviour is inherited?

    It is a cumbersome wording they have chosen. What I believe they mean is that as in ECMAScript, an instance of a class is just another object like anything else, you can modify almost everything about it, while in C++, an instance of a class has stricter requirements. You can't add new methods to an instance, you can't add new properties, and you can't break the constraints that the language has provided for you.

    I hope this answers your questions. If anything isn't clear, please comment and I'll edit it.