Skip to content

Instantly share code, notes, and snippets.

@b-studios
Created May 1, 2015 18:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save b-studios/25037fffae9d4754a553 to your computer and use it in GitHub Desktop.
Save b-studios/25037fffae9d4754a553 to your computer and use it in GitHub Desktop.
JS Imports
<html><script>
// Library Stuff
function assert(b) {
if (!b) { throw "Assertion failed!"; }
}
// binds `this` of f to `obj`
function bind(f, obj) {
return function () {
return f.apply(obj, arguments);
}
}
// convert some array-like object to an array
function toArray(argsObj) {
return [].slice.apply(argsObj);
}
function locally(f) { return f(); }
// This shows standard JS behavior
var module = {
foo: function () { return this.bar; },
bar: 42
}
assert(module.foo() == 42)
with (module) {
assert(foo() == 42)
}
// ReferenceError: foo is not defined
// (function () { assert(foo() == 42)}).apply(module);
var m = Object.create(module);
m.bar = 43;
assert(m.foo() == 43)
var m2 = {
foo: bind(module.foo, module),
bar: 43
}
assert(m2.foo() == 42)
function check(obj, name) {
if (obj[name] === undefined) {
throw '"' + name + '" not defined in "' + obj + '"';
}
return obj;
}
function load(obj, name) {
var el = check(obj, name)[name];
if (typeof el === "function") {
el = bind(el, obj);
}
return el;
}
// Just extracting members of objects to import them.
// (Before: Binding `this` to the original receiver)
locally(function () {
var foo = load(module, 'foo'),
bar = load(module, 'bar');
assert(foo() == 42)
})
// Using `with` for import, but checking before to avoid
// unexpected behavior. Explicitly binding `this` is not
// necessary.
with (check(module, 'foo')) {
assert(foo() == 42)
// this might be unexpected!
bar = 43
assert(foo() == 43)
}
function safe(obj) {
var dummy = {};
toArray(arguments).slice(1).forEach(function (key) {
var el = check(obj, key)[key];
if (typeof el === "function") {
dummy[key] = bind(el, obj);
} else {
dummy[key] = el
}
})
return dummy;
}
// Somewhat safe use of `with`
with (safe(module, 'foo')) {
bar = 43
assert(foo(), 42)
}
function Module(obj) {
return {
load: function () {
var args = [];
toArray(arguments).forEach(function (key) {
var el = check(obj, key)[key];
if (typeof el === "function") {
el = bind(el, obj);
}
args.push(el);
});
return function (f) {
return f.apply(this, args);
}
}
}
}
// More JS idiomatic way (though more verbose)
Module(m).load('foo')(function (foo) {
assert(foo(), 42)
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment