2010
06.21
On a previous project we were writing a web UI using a lot of javascript. The UI was constructed in an MVP style with many Views, Presenters and Models all active at the same time. One of the problems we had was with having multiple Presenters subscribed to listen for a single callback from a Model.
Initially we had quite an ugly solution which involved chaining functions in a similar fashion as to DOM events were handled in the pre jQuery days. To do this we used the following function…
function addEventHandler(event, scope, method) {
var oldEvent = event;
return function() {
var params = [];
for (var i = 0; i < arguments.length; i++) {
params.push(arguments[i]);
}
params.push(this);
oldEvent.apply(this, params);
method.apply(scope, params);
};
}
Example usage…
someObject.someEvent = addEventHandler(someObject.someEvent, this, doSomething);
function doSomething() {
}
After some refactoring we created an Event class (semi inspired by Node.Js EventEmitter). This seemed like a nice way to allow us to simplify the syntax, make it easier to read and attempt to use a familiar syntax to listeners else where in JavaScript.
var Event = function() {
var self = this;
var handlers = [];
self.addListener = function(handler) {
handlers.push(handler);
};
self.trigger = function() {
for(var index in handlers) {
handlers[index].apply(this, getArguments(arguments));
}
};
var getArguments = function(args) {
var params = [];
for (var i = 0; i < args.length; i++) {
params.push(args[i]);
}
return params;
};
};
Example usage…
someObject.someEvent.addListener(doSomething);
function doSomething() {
}
2010
04.30
First thing that struck me when i started working with NodeJS was a lack of anything to run my tests with. I wanted to be able to write tests, run them, tell me which one failed and why. I thought this may be usefull for others so here is “Nest” my node testing module that works with the existing assert module.
Nest @ GitHub
Example
var nest = require("./nest");
var assert = require("assert");
var testCases = new nest.Nest();
testCases.add("TestSomething", {
test_true_is_true: function() {
assert.equal(true, false);
}
});
testCases.run();
2010
03.14
Scope is a little different in NodeJS but only in a artificial sense. let’s dive into a quick example of what i mean.
Circle.js
var PI = 3.14;
exports.getPi = functon() {
return PI;
}
If you were to include this file into a browser you would expect to be able to access the variable PI from another file (ignoring the syntax error which would be created by assigning to the undefined object “exports”). This is not the case in NodeJS, when you call require to include this script the contents of the file is inserted into a function as follows…
var wrapper = "(function (exports, require, module, __filename, __dirname) { "
+ content
+ "\n});";
By calling this wrapper function and passing in an object to the exports parameter, your exported variables/functions are added to the exports object which is then returned as a result of a “require” call.
Because your exported functions are defined inside another function (the one generated when the script is imported) any variables (like PI) are still accessible by your exported functions due to JavaScripts normal scoping. Take a look at JavaScript closures for more information.
Conclusion
- Each script can access what you “require” into it and what you define in it.
- Requires are cached so every call to require for the same module should get a reference to the same thing
- Finally this is my current understanding, ill update as i learn, if you can enlighten me any further leave me a message