ember-data.js failure on script init - javascript

I'm using all of the latest dependencies for emberjs and yet I end up with an error on initializing the scripts in the page at ember-data-latest.min.js with:
Uncaught TypeError: Object function () {...} has no method 'registerInjection'
Before even writing a single line for my app. Why is that?
Appreciate any kind help.
Here's my script list:
jquery-1.10.2.min.js
handlebars-v1.3.0.js
ember-1.5.1.js
ember-states.js
ember-data-latest.min.js
And here's the full error:
Uncaught TypeError: Object function () {
if (!wasApplied) {
Class.proto(); // prepare prototype...
}
o_defineProperty(this, GUID_KEY, nullDescriptor);
o_defineProperty(this, '__nextSuper', undefinedDescriptor);
var m = meta(this), proto = m.proto;
m.proto = this;
if (initMixins) {
// capture locally so we can clear the closed over variable
var mixins = initMixins;
initMixins = null;
this.reopen.apply(this, mixins);
}
if (initProperties) {
// capture locally so we can clear the closed over variable
var props = initProperties;
initProperties = null;
var concatenatedProperties = this.concatenatedProperties;
for (var i = 0, l = props.length; i < l; i++) {
var properties = props[i];
Ember.assert("Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.", !(properties instanceof Ember.Mixin));
if (typeof properties !== 'object' && properties !== undefined) {
throw new Ember.Error("Ember.Object.create only accepts objects.");
}
if (!properties) { continue; }
var keyNames = Ember.keys(properties);
for (var j = 0, ll = keyNames.length; j < ll; j++) {
var keyName = keyNames[j];
if (!properties.hasOwnProperty(keyName)) { continue; }
var value = properties[keyName],
IS_BINDING = Ember.IS_BINDING;
if (IS_BINDING.test(keyName)) {
var bindings = m.bindings;
if (!bindings) {
bindings = m.bindings = {};
} else if (!m.hasOwnProperty('bindings')) {
bindings = m.bindings = o_create(m.bindings);
}
bindings[keyName] = value;
}
var desc = m.descs[keyName];
Ember.assert("Ember.Object.create no longer supports defining computed properties. Define computed properties using extend() or reopen() before calling create().", !(value instanceof Ember.ComputedProperty));
Ember.assert("Ember.Object.create no longer supports defining methods that call _super.", !(typeof value === 'function' && value.toString().indexOf('._super') !== -1));
Ember.assert("`actions` must be provided at extend time, not at create " +
"time, when Ember.ActionHandler is used (i.e. views, " +
"controllers & routes).", !((keyName === 'actions') && Ember.ActionHandler.detect(this)));
if (concatenatedProperties && indexOf(concatenatedProperties, keyName) >= 0) {
var baseValue = this[keyName];
if (baseValue) {
if ('function' === typeof baseValue.concat) {
value = baseValue.concat(value);
} else {
value = Ember.makeArray(baseValue).concat(value);
}
} else {
value = Ember.makeArray(value);
}
}
if (desc) {
desc.set(this, keyName, value);
} else {
if (typeof this.setUnknownProperty === 'function' && !(keyName in this)) {
this.setUnknownProperty(keyName, value);
} else if (MANDATORY_SETTER) {
Ember.defineProperty(this, keyName, null, value); // setup mandatory setter
} else {
this[keyName] = value;
}
}
}
}
}
finishPartial(this, m);
this.init.apply(this, arguments);
m.proto = proto;
finishChains(this);
sendEvent(this, "init");
} has no method 'registerInjection'

You need to make sure to use the latest version which gets published at Ember build site.
The latest build for Ember Data is found here.

Related

How can I create empty JSON keys (nested or not) using a string?

I currently have this code built in JS, but it's really, really ugly.
Is there any better way to approach it?
The way it works basically is pushing a string like app.chat.test to be the key, and value like teststr.
I test the lengths to see if the "parent" key is there, otherwise we build it.
function constructJson(jsonKey, jsonValue){
//REWRITE!!!!!!!!
let jsonObj = langFile;
let jsonKeyArr = jsonKey.split('.')
if (jsonKeyArr.length === 1) {
if (valToAdd === undefined) {
if (jsonObj[jsonKey] === undefined) {
jsonObj[jsonKey] = {}
}
} else {
if (jsonObj[jsonKey] === undefined) {
jsonObj[jsonKey] = valToAdd
}
}
} else if (jsonKeyArr.length === 2) {
if (jsonObj[jsonKeyArr[0]] === undefined) {
jsonObj[jsonKeyArr[0]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] = jsonValue
}
} else if (jsonKeyArr.length === 3) {
if (jsonObj[jsonKeyArr[0]] === undefined) {
jsonObj[jsonKeyArr[0]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] = jsonValue
}
} else if (jsonKeyArr.length === 4) {
if (jsonObj[jsonKeyArr[0]] === undefined) {
jsonObj[jsonKeyArr[0]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]] = jsonValue
}
} else if (jsonKeyArr.length === 5) {
if (jsonObj[jsonKeyArr[0]] === undefined) {
jsonObj[jsonKeyArr[0]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]][jsonKeyArr[4]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]][jsonKeyArr[4]] = jsonValue
}
} else if (jsonKeyArr.length > 5) {
return console.log("Length over 5 not supported yet!")
}
return jsonObj;
}
Regards.
OF course it's possible, a simple loop will perfeclty do the job.
function constructJson(jsonKey, jsonValue){
//REWRITE!!!!!!!!
langFile = {a:{}, foo:{}};// remove this for your own code
var jsonObj = langFile;
var jsonKeyArr = jsonKey.split('.');
var currentValue = jsonObj;
for(var i = 0; i < jsonKeyArr.length;i++){
if(currentValue[jsonKeyArr[i]]===undefined){
currentValue[jsonKeyArr[i]] = {};
}
if(i < jsonKeyArr.length-1){
currentValue = currentValue[jsonKeyArr[i]];
}else{
currentValue[jsonKeyArr[i]] = jsonValue;
}
}
return jsonObj;
}
alert(JSON.stringify(constructJson("a.b.cd.ef", "toto")));
I just assigning to a temporary variable each sublevel. When i'm on the last i'm assigning the value.
Yes you can, using the javascript reduce function on the array created from the splitted string.
function namespaceCreateExceptLast(representationOfElementToCreate, baseNamespace) {
var tokens;
if (typeof representationOfElementToCreate !== 'string')
throw new Error('Expecting string as first parameter');
if (baseNamespace === undefined)
baseNamespace = window;
tokens = representationOfElementToCreate.split('.');
// Remove the last element (which will contain the value)
tokens.pop();
// Use reduce to create part by part your new object
return tokens.reduce(function (prev, property) {
if (typeof prev !== 'object') {
throw Error('One property is already defined but not an object, namespace creation has failed', property);
return undefined;
} else {
if (!prev[property])
prev[property] = {};
return prev[property];
}
}, baseNamespace);
};
Then you can have:
function constructJson(jsonKey, jsonValue){
let jsonObj = langFile;
var lastItem = namespaceCreateExceptLast(jsonKey, jsonObj);
var lastKey = jsonKey.substring(jsonKey.lastIndexOf('.') + 1);
lastItem[lastKey] = jsonValue;
}
I have added some comments and exceptions to help you understand how it's done, but it's mainly based on the reduce function which you can easily get help for (https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/reduce).

How to restore circular references (e.g. "$id") from Json.NET-serialized JSON?

Is there an existing javascript library which will deserialize Json.Net with reference loop handling?
{
"$id": "1",
"AppViewColumns": [
{
"$id": "2",
"AppView": {"$ref":"1"},
"ColumnID": 1,
}
]
}
this should deserialize to an object with a reference loop between the object in the array and the outer object
The answers given almost worked for me, but the latest version of MVC, JSON.Net, and DNX uses "$ref" and "$id", and they may be out of order. So I've modified user2864740's answer.
I should note that this code does not handle array references, which are also possible.
function RestoreJsonNetReferences(g) {
var ids = {};
function getIds(s) {
// we care naught about primitives
if (s === null || typeof s !== "object") { return s; }
var id = s['$id'];
if (typeof id != "undefined") {
delete s['$id'];
// either return previously known object, or
// remember this object linking for later
if (ids[id]) {
throw "Duplicate ID " + id + "found.";
}
ids[id] = s;
}
// then, recursively for each key/index, relink the sub-graph
if (s.hasOwnProperty('length')) {
// array or array-like; a different guard may be more appropriate
for (var i = 0; i < s.length; i++) {
getIds(s[i]);
}
} else {
// other objects
for (var p in s) {
if (s.hasOwnProperty(p)) {
getIds(s[p]);
}
}
}
}
function relink(s) {
// we care naught about primitives
if (s === null || typeof s !== "object") { return s; }
var id = s['$ref'];
delete s['$ref'];
// either return previously known object, or
// remember this object linking for later
if (typeof id != "undefined") {
return ids[id];
}
// then, recursively for each key/index, relink the sub-graph
if (s.hasOwnProperty('length')) {
// array or array-like; a different guard may be more appropriate
for (var i = 0; i < s.length; i++) {
s[i] = relink(s[i]);
}
} else {
// other objects
for (var p in s) {
if (s.hasOwnProperty(p)) {
s[p] = relink(s[p]);
}
}
}
return s;
}
getIds(g);
return relink(g);
}
I'm not aware of existing libraries with such support, but one could use the standard JSON.parse method and then manually walk the result restoring the circular references - it'd just be a simple store/lookup based on the $id property. (A similar approach can be used for reversing the process.)
Here is some sample code that uses such an approach. This code assumes the JSON has already been parsed to the relevant JS object graph - it also modifies the supplied data. YMMV.
function restoreJsonNetCR(g) {
var ids = {};
function relink (s) {
// we care naught about primitives
if (s === null || typeof s !== "object") { return s; }
var id = s['$id'];
delete s['$id'];
// either return previously known object, or
// remember this object linking for later
if (ids[id]) {
return ids[id];
}
ids[id] = s;
// then, recursively for each key/index, relink the sub-graph
if (s.hasOwnProperty('length')) {
// array or array-like; a different guard may be more appropriate
for (var i = 0; i < s.length; i++) {
s[i] = relink(s[i]);
}
} else {
// other objects
for (var p in s) {
if (s.hasOwnProperty(p)) {
s[p] = relink(s[p]);
}
}
}
return s;
}
return relink(g);
}
And the usage
var d = {
"$id": "1",
"AppViewColumns": [
{
"$id": "2",
"AppView": {"$id":"1"},
"ColumnID": 1,
}
]
};
d = restoreJsonNetCR(d);
// the following works well in Chrome, YMMV in other developer tools
console.log(d);
DrSammyD created an underscore plugin variant with round-trip support.
Ok so I created a more robust method which will use $id as well as $ref, because that's actually how json.net handles circular references. Also you have to get your references after the id has been registered otherwise it won't find the object that's been referenced, so I also have to hold the objects that are requesting the reference, along with the property they want to set and the id they are requesting.
This is heavily lodash/underscore based
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define(['lodash'], factory);
} else {
factory(_);
}
})(function (_) {
var opts = {
refProp: '$ref',
idProp: '$id',
clone: true
};
_.mixin({
relink: function (obj, optsParam) {
var options = optsParam !== undefined ? optsParam : {};
_.defaults(options, _.relink.prototype.opts);
obj = options.clone ? _.clone(obj, true) : obj;
var ids = {};
var refs = [];
function rl(s) {
// we care naught about primitives
if (!_.isObject(s)) {
return s;
}
if (s[options.refProp]) {
return null;
}
if (s[options.idProp] === 0 || s[options.idProp]) {
ids[s[options.idProp]] = s;
}
delete s[options.idProp];
_(s).pairs().each(function (pair) {
if (pair[1]) {
s[pair[0]] = rl(pair[1]);
if (s[pair[0]] === null) {
if (pair[1][options.refProp] !== undefined) {
refs.push({ 'parent': s, 'prop': pair[0], 'ref': pair[1][options.refProp] });
}
}
}
});
return s;
}
var partialLink = rl(obj);
_(refs).each(function (recordedRef) {
recordedRef['parent'][recordedRef['prop']] = ids[recordedRef['ref']] || {};
});
return partialLink;
},
resolve: function (obj, optsParam) {
var options = optsParam !== undefined ? optsParam : {};
_.defaults(options, _.resolve.prototype.opts);
obj = options.clone ? _.clone(obj, true) : obj;
var objs = [{}];
function rs(s) {
// we care naught about primitives
if (!_.isObject(s)) {
return s;
}
var replacementObj = {};
if (objs.indexOf(s) != -1) {
replacementObj[options.refProp] = objs.indexOf(s);
return replacementObj;
}
objs.push(s);
s[options.idProp] = objs.indexOf(s);
_(s).pairs().each(function (pair) {
s[pair[0]] = rs(pair[1]);
});
return s;
}
return rs(obj);
}
});
_(_.resolve.prototype).assign({ opts: opts });
_(_.relink.prototype).assign({ opts: opts });
});
I created a gist here

JS: How to return 'undefined' instead of throwing error 'cannot read property x of undefined'

What is the best way to have js return undefined rather than throw an error when a parent property does not exist?
Example
a = {}
b = a.x.y.z
// Error: Cannot read property 'value' of undefined
// Target result: b = undefined
You have to check for the existence of each property:
var b;
if (a.x && a.x.y && a.x.y.z) {
b = a.x.y.z
}
Or, simliar to another poster's "safeGet" function:
var get = function (obj, ns) {
var y = ns.split('.');
for(var i = 0; i < y.length; i += 1) {
if (obj[y[i]]) {
obj = obj[y[i]];
} else {
return;
}
}
return obj;
};
Use:
var b = get(a, 'x.y.z');
try {
a = {}
b = a.x.y.z
}
catch (e) {
b = void 0;
}
I would go for slightly verbose:
var b = ((a.x || {}).y || {}).z
you could write a safeGet helper function, something like:
edited for drilldown as suggested in comments by arcyqwerty
var getter = function (collection, key) {
if (collection.hasOwnProperty(key)) {
return collection[key];
} else {
return undefined;
}
};
var drillDown = function (keys, currentIndex, collection) {
var max = keys.length - 1;
var key = keys[currentIndex];
if (typeof collection === 'undefined') {
return undefined;
}
if (currentIndex === max) {
return getter(collection, key);
} else {
return drillDown(keys, currentIndex + 1,
getter(collection, key));
}
};
var safeGet = function (collection, key) {
if (key.indexOf(".") !== -1) {
return drillDown(key.split("."), 0, collection);
} else {
return getter(collection, key);
}
};
a = { x: 1 };
b = safeGet(a, 'x.y.z');
http://jsfiddle.net/YqdWH/2/

What does Dart's output look like?

Dart, Google's new web language, says it supports outputting to JavaScript.
What does a simple conversion look like?
main() {
print('Hello, Dart!');
}
When compiled with dart2js (as of 2013-04-26) (see note at bottom) it is converted into:
// Generated by dart2js, the Dart to JavaScript compiler.
// The code supports the following hooks:
// dartPrint(message) - if this function is defined it is called
// instead of the Dart [print] method.
// dartMainRunner(main) - if this function is defined, the Dart [main]
// method will not be invoked directly.
// Instead, a closure that will invoke [main] is
// passed to [dartMainRunner].
function Isolate() {}
init();
var $ = Isolate.$isolateProperties;
// Bound closures
$.Primitives_printString = function(string) {
if (typeof dartPrint == "function") {
dartPrint(string);
return;
}
if (typeof window == "object") {
if (typeof console == "object")
console.log(string);
return;
}
if (typeof print == "function") {
print(string);
return;
}
throw "Unable to print message: " + String(string);
};
$.main = function() {
$.Primitives_printString("Hello, Dart!");
};
$.String = {builtin$cls: "String"};
var $ = null;
Isolate = Isolate.$finishIsolateConstructor(Isolate);
var $ = new Isolate();
// BEGIN invoke [main].
if (typeof document !== "undefined" && document.readyState !== "complete") {
document.addEventListener("readystatechange", function () {
if (document.readyState == "complete") {
if (typeof dartMainRunner === "function") {
dartMainRunner(function() { $.main(); });
} else {
$.main();
}
}
}, false);
} else {
if (typeof dartMainRunner === "function") {
dartMainRunner(function() { $.main(); });
} else {
$.main();
}
}
// END invoke [main].
function init() {
Isolate.$isolateProperties = {};
Isolate.$finishIsolateConstructor = function(oldIsolate) {
var isolateProperties = oldIsolate.$isolateProperties;
isolateProperties.$currentScript = typeof document == "object" ? document.currentScript || document.scripts[document.scripts.length - 1] : null;
var isolatePrototype = oldIsolate.prototype;
var str = "{\n";
str += "var properties = Isolate.$isolateProperties;\n";
var hasOwnProperty = Object.prototype.hasOwnProperty;
for (var staticName in isolateProperties) {
if (hasOwnProperty.call(isolateProperties, staticName)) {
str += "this." + staticName + "= properties." + staticName + ";\n";
}
}
str += "}\n";
var newIsolate = new Function(str);
newIsolate.prototype = isolatePrototype;
isolatePrototype.constructor = newIsolate;
newIsolate.$isolateProperties = isolateProperties;
return newIsolate;
};
}
//# sourceMappingURL=out.js.map
Note for posterity: The original answer to this question has been modified to reflect the current state of affairs.
On 2012-05-12 the dart output for Hello World was 18,718 characters.
On 2012-08-29 the output was 1531 characters.
On 2013-04-26, the output was 2642 characters.
dart2js can minify code. Here is an example (as of 2013-04-26)
// Generated by dart2js, the Dart to JavaScript compiler.
function I(){}
init()
var $=I.p
$.ib=function(a){if(typeof dartPrint=="function"){dartPrint(a)
return}if(typeof window=="object"){if(typeof console=="object")console.log(a)
return}if(typeof print=="function"){print(a)
return}throw "Unable to print message: " + String(a)}
$.E2=function(){$.ib("Hello, Dart!")}
$.qU={builtin$cls:"qU"}
var $=null
I = I.$finishIsolateConstructor(I)
var $=new I()
if (typeof document !== "undefined" && document.readyState !== "complete") {
document.addEventListener("readystatechange", function () {
if (document.readyState == "complete") {
if (typeof dartMainRunner === "function") {
dartMainRunner(function() { $.E2(); });
} else {
$.E2();
}
}
}, false);
} else {
if (typeof dartMainRunner === "function") {
dartMainRunner(function() { $.E2(); });
} else {
$.E2();
}
}
function init(){I.p={}
I.$finishIsolateConstructor=function(a){var z=a.p
z.$currentScript=typeof document=="object"?document.currentScript||document.scripts[document.scripts.length-1]:null
var y=a.prototype
var x="{\n"
x+="var properties = I.p;\n"
var w=Object.prototype.hasOwnProperty
for(var v in z){if(w.call(z,v)){x+="this."+v+"= properties."+v+";\n"}}x+="}\n"
var u=new Function(x)
u.prototype=y
y.constructor=u
u.p=z
return u}}//# sourceMappingURL=out.js.map
On 2013-04-26, the minified code was 1386 characters.
The output of the Dart->JavaScript compiler is a moving target. The first release (technical preview) didn't do a lot of tree shaking and was thus pretty big.
The new (experimental) frog compiler is much better in this respect (David Chandler's blog), but I expect DartC to improve considerably too.

javascript convert dotnotation string into objects

I have a string like this "namespace.fun1.fun2.fun3" passed from the client. It's telling the server which function to use.
How do I safely run the function?
right now i'm doing:
var runthis = string.split('.')
namespace[runthis[1]][runthis[2]][runthis[3]]
How do I handle arbitrary depth of nesting safely?
A little function I wrote. I use it in most of my applications:
Object.lookup = (function _lookup() {
var cache = { };
return function _lookupClosure( lookup, failGracefully ) {
var check = null,
chain = [ ],
lastkey = '';
if( typeof lookup === 'string' ) {
if( cache[ lookup ] ) {
chain = cache[ lookup ].chain;
check = cache[ lookup ].check;
}
else {
lookup.split( /\./ ).forEach(function _forEach( key, index, arr ) {
if( check ) {
if( typeof check === 'object' ) {
if( key in check ) {
chain.push( check = check[ key ] );
lastkey = key;
}
else {
if( !failGracefully ) {
throw new TypeError( 'cannot resolve "' + key + '" in ' + lastkey );
}
}
}
else {
if( !failGracefully ) {
throw new TypeError( '"' + check + '" ' + ' does not seem to be an object' );
}
}
}
else {
lastkey = key;
chain.push( check = window[ key ] );
}
});
if( check ) {
cache[ lookup ] = {
chain: chain,
check: check
};
}
}
}
return {
execute: function _execute() {
return typeof check === 'function' ? check.apply( chain[chain.length - 2], arguments ) : null;
},
get: function _get() {
return check;
}
};
}
}());
usage:
Object.lookup( 'namespace.fun1.fun2.fun3' ).execute();
The first parameter is the object/method/property to resolve. The second (optional) parameter indicates whether or not the lookup() method shall fail silently or throw an exception if some property or object could not get resolved. default is 'throw'. To avoid that call
Object.lookup( 'namespace.fun1.fun2.fun3', true ).execute( 'with', 'paras' );
If .fun3 is a function, you can pass in any parameters into .execute() instead.
if you just want to receive the property value, you can also call .get() instead of .execute()
var val = Object.lookup( 'namespace.fun1.fun2.fun3' ).get();
(I may be misinterpreting the question, but this is what came to mind)
var s = "space.f.g.h.i.j.k.l.m",
a = s.split( "." ),
fn = eval( a[0] );
for ( var i = 1; i < a.length; i++ ) {
fn = fn[ a[i] ];
}
fn();
Note: this won't guard against the namespace being specified incorrectly or maliciously.
This should do:
var get = function(obj, key) {
var s = key.split('.')
, i = 1
, l = s.length;
for (; i < l; i++) {
obj = obj[s[i]];
if (!obj) return;
}
return obj;
};
get({hello:{world:{}}}, 'ns.hello.world');
edit: changed code a bit
Here's a simple for loop that should do find each object specified strating from the global scope, and then run the function it finds.
window.namespace = { fun1: { fun2: { fun3: function() { alert('hi!') }}}};
runFunc = function(address) {
var addressArray = address.split('.'),
current = window,
i = 0;
for (i = 0; i < addressArray.length; i++) {
current = current[addressArray[i]];
}
current();
};
runFunc('namespace.fun1.fun2.fun3');
http://jsfiddle.net/jfWra/1/
And here's some eror protection that will throw something meaningful if the value referenced doesnt exist or is not a function: http://jsfiddle.net/jfWra/2/
Here's another simple solution using a recursive function:
function run(str, context) {
var path = str.split(".")
if path.length == 1 {
context[path[0]].call()
return;
}
if(typeof context == 'undefined') {
context = window[path[0]]
} else {
context = context[path[0]]
}
run(path.splice(1).join('.'), context)
}
Two years later there is this module: https://github.com/daaku/nodejs-dotaccess.
var get = require("dotaccess").get;
var o = {a:{b:{c:'deep'}}};
console.log(get(o, 'a.b.c'));

Categories