1

Based on a question I asked prior to this, how would I qualify this string...

"MyCustomObject.prototype.foo.bar"

to this:

window['MyCustomObject']['prototype']['foo']['bar']

in object form? (it must not qualify to...

"window['MyCustomObject']['prototype']['foo']['bar']"

...as a string!).

As a reference, consider the following...(the code is wrong...it needs fixing (without the eval keyword))

var fn = "MyCustomObject.prototype.foo.bar";
var ptr = fn.split('.');
var ptrPath = 'window'
for(var index = 0; index < ptr.length; index++) {
    ptrPath += '[\'' + ptr[index] + '\']';
}
ptrPath = function() {
    alert("Hello");
}

should resolve to this;

var inst = new MyObject();
inst.foo.bar();  //alerts...."Hello"
Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Matthew Layton
  • 39,871
  • 52
  • 185
  • 313

3 Answers3

0

I modified the answer in this question to suit your needs.

var getPropertyByName = function (fullString, context) {
        var namespaces = fullString.split(".");
        var functionName = namespaces.pop();

        for (var i = 0; i < namespaces.length; i++) {
            context = context[namespaces[i]];
        }

        return context[functionName];
};

getPropertyByName('MyCustomObject.foo.bar', window);

http://jsfiddle.net/jbabey/4GVUK/

Community
  • 1
  • 1
jbabey
  • 45,965
  • 12
  • 71
  • 94
  • does your solution require 'MyCustomObject.foo.bar' to be implemented before it can return something other than undefined? - basically I want a function that qualifies the string into (in this case) a property, and then can assign to (or implement) the property, but it will sometimes be possible that the property does not exist in the first place, therefore the function assignment will be the first time the property becomes defined...I hope this makes sense!? – Matthew Layton Aug 30 '12 at 19:46
  • @activwerx no, it will only work if it has already been defined – jbabey Aug 30 '12 at 19:51
  • :-( is there any way that it can be done? for example, I can do window['CustomObject'] = function() { }; and then I will have a constructable object called, CustomObject, but i want to be able to do the same for nested properties – Matthew Layton Aug 30 '12 at 19:56
  • I have finally worked out what I was trying to do, please consider my answer, and give feedback or critique as appropriate. – Matthew Layton Aug 31 '12 at 12:04
0

You could try this way:

var fn = "foo.prototype.bar";
var ptr = fn.split('.');
var func = ptr.reduce(function(a, b){
    return a[b] ? a[b] : a;
}, window);

The working demo.

xdazz
  • 158,678
  • 38
  • 247
  • 274
  • I have finally worked out what I was trying to do, please consider my answer, and give feedback or critique as appropriate. – Matthew Layton Aug 31 '12 at 12:05
0

Finally after much effort, I have figured out the solution.

The idea behind the Object.implement function is to allow a developer to:

  1. Define an object/function by name (E.G. "Custom" or "Custom.prototype.foo.bar"), regardless of that objects existence.

  2. Define the object/functions context (E.G window)

  3. Define the object/function implementation

  4. define whether to override the object/function if an implementation already exists.

Consider the Object.implement code sample:

Object.implement = function(fn, context, implementation, override) {
    var properties = fn.split('.');
    var fnName = properties.pop();
    for(var index = 0; index < properties.length; index++) {
        if(!context[properties[index]]) {
            context[properties[index]] = { };
        }
        context = context[properties[index]];
    }
    if(!context[fnName] || override) {
        context[fnName] = implementation;
    }
};

I can now use this to safely create/implement objects and functions. Consider this a bit like a "shim" feature, where if a function does not exist, an implementation can be provided, however with the added functionality that existing functionality can be over-ridden as well:

Object.implement("HashTable", window, function() { }, true);
Object.implement("HashTable.prototype.bar", window, function() { alert("Hello World") }, true);

var ht = new HashTable();
ht.bar();

It works in FireFox...I have yet to test in other browsers!

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313