Search code examples
javascriptinheritancerevealing-module-pattern

The equivalent to using __proto__?


I'm trying to use the revealing module pattern with inheritance. I seem to have it working fine, but it uses "__proto__", which I understand it's considered deprecated. Is there a better was to create the inheritance with out using "__proto__"?

var Person = (function() {
    var _name;
    var api = {
        init: init,
        getName: getName
    }
    return api;

    function init(name) {
        _name = name;
    }

    function getName() {
        return _name;
    }
}())

var Teacher = (function() {
    var _subject = "Math";
    var api = {
        getSubject: getSubject,
        say: say
    }
    api.__proto__ = Person;
    return api;

    function getSubject() {
        return _subject;
    }

    function say() {
        console.log("I am " + this.getName() + " and I teach " + _subject)
    }
}());

Teacher.init("Bob");
Teacher.say() //  I am Bob and I teach math

https://plnkr.co/edit/XbGx38oCyvRn79xnn2FR?p=preview


Solution

  • The direct equivalent – setting the prototype, still a bad idea – is Object.setPrototypeOf:

    Object.setPrototypeOf(api, Person);
    

    The normal way of creating an object based on a prototype with Object.create and then adding properties to it works fine here, though:

    var api = Object.create(Person);
    api.getSubject = getSubject;
    api.say = say;
    

    but ideally you would just use constructors:

    class Person {
        constructor(name) {
            this._name = name;
        }
    
        getName() {
            return this._name;
        }
    }
    
    class Teacher extends Person {
        constructor(name) {
            super(name);
            this._subject = 'Math';
        }
    
        getSubject() {
            return this._subject;
        }
    
        say() {
            console.log(`I am ${this.getName()} and I teach ${this.getSubject()}`);
        }
    }
    
    var teacher = new Teacher('Bob');
    teacher.say() //  I am Bob and I teach math
    

    without ES6:

    function Person(name) {
        this._name = name;
    }
    
    Person.prototype.getName = function () {
        return this._name;
    };
    
    function Teacher(name) {
        Person.call(this, name);
        this._subject = 'Math';
    }
    
    Teacher.prototype = Object.create(Person.prototype);
    
    Teacher.prototype.getSubject = function () {
        return this._subject;
    };
    
    Teacher.prototype.say = function () {
        console.log('I am ' + this.getName() + ' and I teach ' + this.getSubject());
    };
    
    var teacher = new Teacher('Bob');
    teacher.say();  // I am Bob and I teach math