Skip to content

Instantly share code, notes, and snippets.

@jupiterjs
Created April 29, 2011 16:13
Show Gist options
  • Save jupiterjs/948547 to your computer and use it in GitHub Desktop.
Save jupiterjs/948547 to your computer and use it in GitHub Desktop.
A proxy loader
(function(){
var getObject = function(name){
var parts = name.split('.'),
current = window,
part;
while(part = parts.shift()){
current = current[part];
}
return current;
},
count = 0,
p = function(currentName, obj){
var obj = obj || window;
var proxy = Proxy.create({
// Fundamental traps IGNORE THIS PART
getOwnPropertyDescriptor: function(name) {
var desc = Object.getOwnPropertyDescriptor(obj, name);
if (desc !== undefined) { desc.configurable = true; }
return desc;
},
getPropertyDescriptor: function(name) {
var desc = Object.getOwnPropertyDescriptor(obj, name);
if (desc !== undefined) { desc.configurable = true; }
return desc;
},
getOwnPropertyNames: function() {
return Object.getOwnPropertyNames(obj);
},
getPropertyNames: function() {
return Object.getPropertyNames(obj); // not in ES5
},
defineProperty: function(name, desc) {
Object.defineProperty(obj, name, desc);
},
fix: function() {
if (Object.isFrozen(obj)) {
return Object.getOwnPropertyNames(obj).map(function(name) {
return Object.getOwnPropertyDescriptor(obj, name);
});
}
return undefined; // will cause a TypeError to be thrown
},
delete: function(name) { return delete obj[name]; },
// IMPORTANT ... magic happens here
get : function(rcvr, prop){
// if our object has a value, return it
if(obj[prop] !== undefined){
return obj[prop];
}
// otherwise we'll try to load it from the server
var clssName = (currentName ? currentName+"." : "") +prop,
path = ( clssName +".js").toLowerCase(),
response = steal.request( path ),
clss;
// if we didn't get anything, make a dummy namespace object
if(!response){
obj[prop] = p(clssName,{});
return obj[prop];
} else {
// eval the script
eval(response);
// get the object
clss = getObject(clssName);
//return a proxy to the object that will also be able to load scripts
return p(clssName, clss);
}
}
})
return proxy;
};
N = p();
})();
// use the namespace to load things!
var users = N.App.Models.User.findAll();
console.log( N.App.Util.String.capitalize(users[0].name) );
@jupiterjs
Copy link
Author

N is a loader that uses a synchronous Ajax request to look for a file that defines an object. The idea is that, similar to rails, Object that aren't defined are looked up on the filesystem (in this case a server). For example:

N.App.Models.User.findAll();

Looks for:

  • app.js
  • app.models.js
  • app.models.user.js

app.models.user.js looks like:

App.Models.User = {
    findAll : function(){
        return [{
            name : "meyer"
        }]
    }
};

It then looks looking for app.util.js and app.util.string.js. It finds app.util.string.js like:

App.Util.String = {
    capitalize : function(s){
        return s.charAt(0).toUpperCase()+s.substr(1);
    }
}

And uses it's capitalize function to capitalize Meyer.

Practical Considerations

This would be terrible to use. It makes requests for scripts that don't exist. Plus it runs synchronously. Still, it's a step towards enabling a more 'care-free' JS dependency management system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment