Реализовать метод extend (задача)

by termi

HTML

<div id="menu">
    <a class="js-ctrl">Toggler</a>
    <div class="js-menu collapsed">
        <ul>
            <li>item 1</li>
            <li>item 2</li>
            <li>item 3</li>
        </ul>
    </div>
</div>

CSS

body {
    margin: 20px;
    font-size: 18px;
    font-family: Geneva, Arial, Helvetica, sans-serif; 
}


.collapsed {
    display: none;
}

a { color: #03c; cursor: pointer; }
a:active { color: red; }

JavaScript

function Class() {}
Class.extend = function extend(desc) {    
    var cons = desc.constructor || function(){};
    cons.prototype = Object.create(this.prototype);
    cons.extend = extend;
    
    Object.keys(desc).forEach(function(key) {
        Object.defineProperty(this, key, Object.getOwnPropertyDescriptor(desc, key));
    }, cons.prototype);
    
    return cons;
};


/** @class Widget */
var Widget = Class.extend({
    constructor: function (el, options) {
        this.el = el;
        this.options = options;
    },
    
    $: function (selector) {
        return this.el.querySelector(selector);
    }
});

/** @class Dropdown */
/** @extends Widget */
var Dropdown = Widget.extend({
    constructor: function () {
        Widget.apply(this, arguments);
        this.$('.js-ctrl').addEventListener('click', this);
    },
    
    handleEvent: function (evt) {
        this.toggle();
    },
    
    toggle: function (evt) {
        var menu = this.$('.js-menu');
        menu.classList.toggle('collapsed');
    }
});


// Используем
var dd = new Dropdown(menu);

// Тесты
console.info('dd is Dropdown:', dd instanceof Dropdown);
console.info('dd is Widget:', dd instanceof Widget);
console.info('dd is Class:', dd instanceof Class);