Menialov Mykhailo

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);
What I cannot create, I do not understand - Blog - Meniailov Mykhailo