Last active
October 10, 2015 22:17
-
-
Save AutoSponge/3758975 to your computer and use it in GitHub Desktop.
simple get
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* null-safe retrieval of objects and their property values from context | |
* @function get | |
* @param {String|String[]} path | |
* @param {Object} [obj=this] | |
* @return | |
*/ | |
(function (HEAD) { | |
var depthCache = {}; | |
var cache = {}; | |
function getDepth(depth) { | |
if (!depthCache[depth]) { | |
var params = ""; | |
var vars = " var _0 = this"; | |
var body = false; | |
var h, i; | |
for (i = 0; i < depth; i += 1) { | |
params += i ? (", $" + i) : "$" + i; | |
vars += i ? (", _" + i) : ""; | |
} | |
vars += ";\n"; | |
for (h = i - 1; i > 0; i -= 1, h -= 1) { | |
if (!body) { | |
body = "_" + h + " === Object(_" + h + ") && ($" + h + " in _" + h + ") ? _" + h + "[$" + h + "]"; | |
} else { | |
body = "(_" + i + " = _" + h + "[$" + h + "], _" + i + ") && " + body; | |
} | |
} | |
body = " return " + (!body ? "_0;" : body + " : void(0);"); | |
depthCache[depth] = Function(params, vars + body); | |
} | |
return depthCache[depth]; | |
} | |
function get(path, obj) { | |
var params = path ? path.split ? cache[path] || (cache[path] = path.split("."), cache[path]) : path : []; | |
return getDepth(params.length).apply(obj || this, params); | |
} | |
HEAD.get = get; | |
}(this)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//setup test objects | |
(function (HEAD) { | |
var paths = {}; | |
HEAD.paths = paths; | |
HEAD.obj = (function (start, end) { | |
var i, next, obj, path, name; | |
next = obj = {}; | |
path = ""; | |
for (i = 0; i < (end - start); i += 1) { | |
name = String.fromCharCode(i + start); | |
next = next[name] = (i%3 < 2 ? {} : i%2 === 0 ? [] : function () {}); | |
path += path.length ? "." + name : name; | |
paths[i + 1] = path; | |
} | |
return obj; | |
}(97, 123)); | |
}(this)); | |
//run tests | |
(function (tests, HEAD) { | |
var i = tests.length; | |
var test; | |
while (i--) { | |
test = tests[i]; | |
if (test !== "ignore") { | |
switch (test[0]) { | |
case "type": | |
console.assert(typeof get(test[2], test[3]) === test[4], test[1]); | |
break; | |
case "instance": | |
console.assert(get(test[2], test[3]) instanceof test[4], test[1]); | |
break; | |
default: | |
console.assert(get(test[2], test[3]) === test[4], test[1]); | |
} | |
} | |
} | |
}([ | |
//type message param1 param2 equals | |
["equals", "should get global from global", , , this], | |
["equals", "should get obj from global", "obj", , obj], | |
["equals", "should get obj from obj", null, obj, obj], | |
["equals", "should get obj from obj", , obj, obj], | |
["equals", "should get obj from obj at depth 0", paths[0], obj, obj], | |
["equals", "should get a from obj at depth 1", paths[1], obj, obj.a], | |
["equals", "should get z from obj at depth 26", paths[26], obj, obj.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z], | |
["equals", "should not get x from a at depth 2", paths[1] + ".x", obj, ], | |
["equals", "should not get x from a at depth 3", paths[1] + ".x.x", obj, ], | |
["instance","should return an array c from b", paths[3], obj, Array], | |
["equals", "should return length 0 from array c", paths[3] + ".length", obj, 0], | |
["equals", "should return length 0 from array c", ["a", "b", "c", "length"], obj, 0], | |
["type", "should return a function f from e", paths[6], obj, "function"], | |
["type", "should return a function apply from f", paths[6] + ".apply", obj, "function"], | |
["equals", "should return f.apply.length", paths[6] + ".apply.length", obj, 2], | |
["equals", "should get d from obj at depth 4", ["a", "b", "c", "d"], obj, obj.a.b.c.d], | |
"ignore" | |
], this)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function send(fn, args, obj) { | |
var f = fn; | |
var o = this || obj; | |
if (typeof fn === "string") { | |
f = get(fn, o); | |
} | |
return f.apply(o, args); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment