Friday, January 22nd, 2010
De-fusing JavaScript Natives with the Fusebox
<p>John-David Dalton has released Fusebox, a library that allows you to sandbox natives:Extending JavaScript natives gives you the power to customize the language to fit your needs. You can add convenience methods like "hello world".capitalize() or implement missing functionality like [1,2,3].indexOf(2) in JScript. The problem is that frameworks / libraries / third-party scripts may overwrite native methods or each other's custom methods resulting in unpredictable outcomes. Fusebox, a limited version of the sandboxing component found in FuseJS, avoids these issues by creating sandboxed natives which can be extended without affecting the document natives.
For example:
JAVASCRIPT:
var fb = Fusebox(); fb.Array.prototype.hai = function() { return "Oh hai, we have " + this.length + " items."; }; fb.Array(1,2,3).hai(); // "Oh hai, we have 3 items." typeof window.Array.prototype.hai; // undefined
John has a series of short screencasts to introduce the topic of sandboxed natives, how to use them, and the techniques used to make it all happen:
- Sandboxed Natives 101: Screencast One
- How to create a sandbox: Screencast Two
- How to create a Fusebox: Screencast Three
- The Final Countdown: Screencast Four
Great to learn from. It is a shame that you have to remember to use a very different way to access the types of course and that you have to do all of this magic.... but with JavaScript, it is what it is!
Related Content:











This seems similar to the standard I’m proposing.
http://wiki.ecmascript.org/doku.php?id=strawman:modules_primordials
So, the “sandbox” only works if the third-party scripts make sure they only modify the fusebox instances (fb.Array, fb.String, etc) and not the real global object? Not much of a sandbox.
Saw the 2008-2010 in the source, now that’s dedication. Great piece of work.
@Stakka — as I understand it, only in IE will modifications to the normal natives actually creep into the sandbox’d natives. And even then, it shouldn’t “break” the sandboxes as modifying real natives does (foreach, etc).
.
The key is to start insisting on using the sandbox’d natives for all your extending needs and leave the real natives alone. If you do that, you should see an improvement in your code and functionality.
@getify – If you’re the one modifying the built-in global objects. Then why use fusebox, when you can just stop modifying the objects in the first place?
@Stakka – because there are valid use cases for extending natives… giving them features that arguably they should already have… makes code cleaner and in some cases more efficient. But the caveats of extending true natives have made most people shy away from them.
.
Fusebox kind of solves that as it gives you a safe way to extend them without the negative side effects, and still get all the improvements to the rest of the code that extended natives gives.
There’s a framework named “Fusebox”, for ColdFusion, that’s been around for 10+ years.
@Stakka – I released Fusebox as a standalone because it is unique & some may find it interesting. Its primary use is in FuseJS (fuse.Fusebox), which only modifies Fuseboxed natives and not ones on the global. It seems like what you expected was something to sandbox existing frameworks which is not the purpose/function of Fusebox.
.
@getify – The gotcha on things creeping into the sandbox is addressed in the README.markdown.
.
@getify – Your last comment is right on the mark. Ditto :D
I experimented with Sandboxed natives too, but in different way. http://github.com/Steida/PJ/blob/master/index.html
But debuggers don’t like code from other scope. So I decided, if I would ever again want to use js code which modifies prototype, I would prefer invisible iframe rather. It’s clean a no hacky.
@Stakka:
Interested in a library that doesn’t work with “fusebox” types?
http://blog.higher-order.net/2010/01/22/fuse-blows/
Sort of the same principle but not quite. But it allows working with the native types in the script. ;-)
Cheers,
- Karl
@willpeavy: I am a Fuseboxer (CF and PHP both) too, so the title of this article made me look twice too. An interesting read nonetheless…
I am very impressed that the Fusebox approach was able to get the array notation [] to work with get/set. When I played around with extending the native data types, I had to rely on push/pop. Very slick!