0

Scenario

I have an object with a lot of properties and methods, and suppose it's stored in Global.Framework. Now, I have another object called User and I want to provide it access to Global.Framework by cloning the .Framework to User.

However, User also has a property called Name, (stored in User.Name) which needs to be passed to each framework's methods as the first argument, transparently.

Example Code

For example, in the method declarations for Global.Framework, there may be something like

Global.Framework = {
    methodOne: function(name, a, b, c) { /* do something */ },
    methodTwo: function(name, a) { /* do something */ },
    propertyOne: 100,
    propertyTwo: "me"
}

However, I want these methods to be exposed to User.Framework like this: (The properties are simply cloned. They do not need any extra processing)

User.Framework = {
    methodOne: function(a, b, c) {
         return Global.Framework.methodOne(User.Name, a, b, c);
    } (...)

The Problem

Obviously, as the amount of methods in Framework will change, and perhaps even their arguments, I cannot declare them one by one manually in the cloning process.

What I've tried so far

I've looked up how to get the arguments dynamically and found this: How to get function parameter names/values dynamically from javascript

But I am not sure how to make this happen, and it should preferably not use too many processing resources. This is what I am thinking of:

  1. Go through every property in the Framework object, cloning it if not a function, or
  2. Get the arguments list for the function
  3. ?? Rewrite the calls to return functionBeingLooped(User.Name, [the rest of the arguments])

I'm stuck on step 3 and my limited Javascript knowledge reminds me of nothing except eval (which is out of question). Is there a way to accomplish this?

Community
  • 1
  • 1
Jimmie Lin
  • 2,205
  • 2
  • 23
  • 35

1 Answers1

1

You could set all User.Framework functons to a closure (not sure how you clone your Global.Framework).

Here is the pseudo code assuming username comes as the first argument, if it doesn't you're going to have to parse the Global.Framework funtction .toString() value:

var org={};
org.t = function(name, a ,b){
  console.log(arguments);
};


var cloned={};
cloned.name="cloned";
// your cloning method
for(thing in org){
  if(typeof org[thing] === 'function'){
    // if name isn't the first argument then you have to use
    // org[thing].toString() and parse that
    cloned[thing]=function(){
       org[thing].apply(cloned,[cloned.name]
         .concat(Array.prototype.slice
         .call(arguments, 0)));
    }
  }
}

console.log(cloned.t("a","b"));
HMR
  • 37,593
  • 24
  • 91
  • 160
  • There's a small problem here - the `thing` variable is being overwritten every run, and it seems like that when I'm called cloned[a], if it looped through org[a], [b], [c] in that order, calling cloned[anything] will try to call .apply on [c]. How do I resolve this? – Jimmie Lin Jul 17 '13 at 03:38
  • @JimmieLin Do you create multiple instances using some sort of function that returns a cloned version? In that case I need to see the clone function itself. – HMR Jul 17 '13 at 06:34
  • I instead used cloned[thing] = org[thing].bind(null, name) to prepend the `name`. Works now :) – Jimmie Lin Jul 17 '13 at 08:24