Никита Прокопов (tonsky) wrote,
Никита Прокопов
tonsky

Simplifying Javascript inheritance to an understandable state

There’s rarely a week when I don't see an article by another guy who has “finally” figured out how to bring classes to Javascript.

Why is it this way? Javascript inheritance syntax is a mess now. The idea is so simple it could be explained in one sentence (each object has a [[Prototype]] ref, and props are looked up first in object itself, then in obj['[[Prototype]]'], and so on up the inheritance chain); but it maps to Javascript syntax in a really brain-racking way (starting from .prototype property being not that [[Prototype]] but a completly different thing).

I believe that the solution is not to add classes, but to remove needless syntax constructs and make syntax directly reflect underlying inheritance model.

On Gecko engines, there's nothing to do: __proto__ is exactly the [[Prototype]] property and is directly avaliable for reading and writing.

Other browsers need a helper to assign [[Prototype]]:

  var _with = function(proto, overrides) {
      if (!overrides) overrides = {};

      // that's the trick
      var ctor = function() { this.__proto__ = proto; };
      ctor.prototype = proto;
      var child = new ctor();
      // 'child'.[[Prototype]] pseudoproperty is set to 'proto' now
      // and real 'child.__proto__' property added

      for (var prop in overrides)
          if (overrides.hasOwnProperty(prop))
              child[prop] = overrides[prop];
      return child;
  };


This is a classical, bare-bones prototype inheritance as it should be.

You can use it to imitate classes if you want to:


  var Clazz = { 
      x: 10, 
      y: 20, 
      method: function() {
          return this.x;
      },
      method2: function() {
          return this.__proto__.x; // referencing parent
      }
  };
  var DerivedClazz = _with(Clazz, {x: 15});

  var instance = _with(DerivedClazz);
  alert(instance.y);         // 20
  instance.x = 100;
  alert(instance.x);         // 100
  alert(instance.method());  // 100
  alert(instance.method2()); // 15
  alert(DerivedClazz.x);     // 15
  alert(Clazz.x);            // 10


Implementing instanceof is left as an exercise for the reader.

UPD. Ok, Douglas Crockford already invented this more than 5 years ago. Shame on me. However, it also proves this stuff working and being useful.

UPD 2. Still I cannot understand why this stuff isn't ubiquitos or at least implemented in any of js frameworks?

UPD 3. It was added as Object.create in ECMAScript 5, and browsers starting IE 9, Safari 5, Chrome 5, Firefox 4 and Opera 12 support it. Go and use it, do not increase the mess with another 'OO' stuff.
Tags: en, веб-шмеб, девелопмент, идеи, очень просто
Subscribe

  • IPFCP, ой, то есть ICFPC-2020

    Ровно 11 часа назад закончился ICFPC 2020. Так как я предусмотрительно взял выходной на остаток дня, готовьтесь, сейчас буду РАССКАЗЫВАТЬ. Отчет за…

  • Почему JetBrains не напишет легковесную IDE

    Еще в 2011 я публично отказался от ИДЕ и так с тех пор и живу: TextMate, Vim, Sublime, LightTable, VS Code, снова Sublime. И вот год назад я…

  • Продолжаем обобщать и передергивать

    Евгений Трифонов накатал ответку на мой старый Software Disenchantment! На что у меня есть несколько замечаний, по мелочам и по существу. Готов…

  • Post a new comment

    Error

    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 10 comments

  • IPFCP, ой, то есть ICFPC-2020

    Ровно 11 часа назад закончился ICFPC 2020. Так как я предусмотрительно взял выходной на остаток дня, готовьтесь, сейчас буду РАССКАЗЫВАТЬ. Отчет за…

  • Почему JetBrains не напишет легковесную IDE

    Еще в 2011 я публично отказался от ИДЕ и так с тех пор и живу: TextMate, Vim, Sublime, LightTable, VS Code, снова Sublime. И вот год назад я…

  • Продолжаем обобщать и передергивать

    Евгений Трифонов накатал ответку на мой старый Software Disenchantment! На что у меня есть несколько замечаний, по мелочам и по существу. Готов…