-2

I have functions in JS that must be hard-coded for some reason. How do I make a function that writes this hard-coded function? Here's my example; assuming obj is a multi-array/JSON object:

function foo2(obj) {
    var t = obj["key1"];
    t = t["key2"];
    return t;
}

function fooN(obj) {
    var t = obj["key1"];
    t = t["key2"];
    ...//more goes here
    t = t["keyN"];
    return t;
}

I know there're easier ways to access multi-array/object, but hard-coded functions like this is by far the fastest, since there is no variable substitution. Thank you.

Barmar
  • 741,623
  • 53
  • 500
  • 612
Keng
  • 854
  • 10
  • 10
  • 2
    "for some reason." --- that's a bad reason. When something irrational requires write you terrible code - you better avoid it instead. – zerkms May 01 '15 at 04:08
  • 2
    [Premature optimization is the root of all evil.](http://c2.com/cgi/wiki?PrematureOptimization) Did you profile it? Do you know that your execution with nice code is unacceptable, and the hardcoded variant fast enough? Modern JS interpreters are insanely fast, and even in slower languages variable access is considered cheap. – Amadan May 01 '15 at 04:09
  • See [new Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function). It lets you provide the body as a string, and defines the function. – Barmar May 01 '15 at 04:09
  • You don't need to keep assigning variables. `return obj.key1.key2.key3....keyN` – Barmar May 01 '15 at 04:10
  • Don't you think the writers of the most popular JS interpreters have optimized something as commonplace as object-property access as much as it possibly can be? I really doubt your "optimizations" will do much. I wouldn't even be surprised if they slowed down your code. – Shashank May 01 '15 at 04:24

2 Answers2

1

I don't advocate it, but here's how you could do it:

function defineAccessor(propArray) {
  var accessors = propArray.join('.');
  return new Function('obj', 'return obj.' + accessors);
}
var x = { key1: { key2: 3 } };
var foo2 = defineAccessor(['key1', 'key2']);
alert(foo2(x)); // alerts 3
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

Seems like some strange requirements, but a possible solution is to add the functions to window using window['foo' + number].

The main tricky bit in this solution is the closure in the middle that ensures that the correct value of i is used. This is done by calling a function that takes i as an arg and returns a function.

var N = 5;

fooX = function(obj, x) {
  var t = obj["key" + 1];
  for (var i = 2; i <= x; i++) {
    t = t["key" + i];
  }
  return t;
}

for (var i = 1; i <= N; i++) {
  window['foo' + i] = (function(x) {
    return function(obj) {
      return fooX(obj, x);
    }
  })(i);
}


var obj = {
  key1: {
    key2: {
      key3: {
        key4: {
          key5: 5
        }
      }
    }
  }
}

var message = "Results:<br>" +
  "foo1(obj) = " + foo1(obj) + "<br>" +
  "foo2(obj) = " + foo2(obj) + "<br>" +
  "foo3(obj) = " + foo3(obj) + "<br>" +
  "foo4(obj) = " + foo4(obj) + "<br>" +
  "foo5(obj) = " + foo5(obj);

document.body.innerHTML = message;
Daniel Imms
  • 47,944
  • 19
  • 150
  • 166