What I cannot create, I do not understand
I saw a post in Hacker News about Richard Feynman's blackboard at the time of his death. The first comment mentions his motto: "What I cannot create, I don't understand."
This motto matches the Not Invented Here syndrome and how I've been learning programming.
When I first started to get serious about Frontend development, there was Backbone.js. This amazing library abstracted concepts into an easy-to-use API that allowed you to build powerful Frontends.
However, before I started using it, I had an urge to understand it, so as you can see below my own Bone
This post is a glorified bookmark with notes reminding me how I started learning these things.
// Bone.js 0.0.1//// Experiment based on Backbone.js// and highly inspired in https://gist.github.com/g6scheme/4157554/*! Salt.js DOM Selector Lib. By @james2doyle */window.$ = function(selector, context, undefined) { // an object containing the matching keys and native get commands var matches = { '#': 'getElementById', '.': 'getElementsByClassName', '@': 'getElementsByName', '=': 'getElementsByTagName', '*': 'querySelectorAll' }[selector[0]]; // you can treat a string as an array of characters // now pass the selector without the key/first character var el = (((context === undefined) ? document: context)[matches](selector.slice(1))); // if there is one element than return the 0 element return ((el.length < 2) ? el[0]: el);}; ;(function() { // Reference to the global object `window`. var root = this; // Top-level namespace. var Bone; Bone = root.Bone = {}; // Current version of the library. Keep in sync with `package.json`. Bone.VERSION = '0.0.1'; // Require `lo-dash.js`. var _ = root._; // Salt.js owns the `$` variable. Bone.$ = root.$; // Module that can be mixed in to *any object* in order to provide it // with custom events. // // var events = {}; // _.extend(events, Bone.Events); // // // tokenized reference `_vent`. // var _vent = events.on('expand', function() { alert('expanded'); }); // events.trigger('expand'); // // To unsubscribe you need the use the tokenized reference. // events.off(_vent); var Events = Bone.Events = { // Storage for topics that can be broadcast // or listened to _topics: {}, // An topic identified _subUid: -1, // Publish or broadcast events of interest // with a specific topic name and arguments // such as the data to pass along trigger: function(event, args) { if (!this._topics[event]) { return false; } var events = this._topics[event], len = events ? events.length : 0; while (len--) { events[len].callback(event, args); } return this; }, // Suscribe to events of interest // with a specific event name and a // callback function, to be excecuted // when the topic/event is observed on: function(event, callback) { if (!this._topics[event]) { this._topics[event] = []; } var token = (++this._subUid).toString(); this._topics[event].push({ token: token, callback: callback }); return token; }, // Unsuscribe from a specific // topic, based on a tokenized reference // to the subscription off: function(token) { for (var m in this._topics) { if (this._topics[m]) { for (var i = 0, j = this._topics[m].length; i < j; i++) { if (this._topics[m][i].token === token) { this._topics[m].splice(i, 1); return token; } } } } return this; }, }; // ## Model var Model = Bone.Model = function(attributes) { this.id = _.uniqueId('model'); this.attributes = attributes || {}; }; Bone.Model.prototype.get = function(attr) { return this.attributes[attr]; }; Bone.Model.prototype.set = function(attrs) { if (_.isObject(attrs)) { _.extend(this.attributes, attrs); this.change(attrs); console.log("model changed!"); } else { throw "`attrs` is not an `Object`"; } return this; }; Bone.Model.prototype.toJSON = function(opts) { return _.clone(this.attributes); }; Bone.Model.prototype.change = function(attrs) { this.trigger(this.id + 'update', attrs); }; _.extend(Bone.Model.prototype, Bone.Events); // ## View var View = Bone.View = function(opts) { _.extend(this, opts); this.id = _.uniqueId('view'); }; _.extend(Bone.View.prototype, Bone.Events); // ## Controller var Controller = Bone.Controller = function(opts) { _.extend(this, opts); this.id = _.uniqueId('controller'); var parts, selector, eventType; if (this.events) { _.each(this.events, function(method, eventName) { parts = eventName.split(' '); selector = parts[0]; eventType = parts[1]; $(selector)['on' + eventType] = this[method]; }.bind(this)); } };}).call(this);