Alex Rivera | Logout

How to dynamically set a function/object name in Javascript as it is displayed in Chrome

Asked 2011-05-03T14:29:58.443
54

This is something which has been bugging me with the Google Chrome debugger and I was wondering if there was a way to solve it.

I'm working on a large Javascript application, using a lot of object oriented JS (using the Joose framework), and when I debug my code, all my classes are given a non-sensical initial display value. To see what I mean, try this in the Chrome console:

var F = function () {};
var myObj = new F();

console.log(myObj);

The output should be a single line which you can expand to see all the properties of myObj, but the first thing you see is just ▶ F.

My issue is that because of my OO framework, every single object instantiated gets the same 'name'. The code which it looks is responsible for this is like so:

getMutableCopy : function (object) {
    var f = function () {};
    f.prototype = object;
    return new f();
}

Which means that in the debugger, the initial view is always ▶ f.

Now, I really don't want to be changing anything about how Joose instantiates objects (getMutableCopy...?), but if there was something I could add to this so that I could provide my own name, that would be great.

Some things that I've looked at, but couldn't get anywhere with:

> function foo {}
> foo.name
  "foo"
> foo.name = "bar"
  "bar"
> foo.name
  "foo"    // <-- looks like it is read only
Edit
Report

1 Answer

5

Although it is ugly, you could cheat via eval():

function copy(parent, name){
  name = typeof name==='undefined'?'Foobar':name;
  var f = eval('function '+name+'(){};'+name);
  f.prototype = parent;
  return new f();
}

var parent = {a:50};
var child = copy(parent, 'MyName');
console.log(child); // Shows 'MyName' in Chrome console.

Beware: You can only use names which would be valid as function names!

Addendum: To avoid evaling on every object instantiation, use a cache:

function Cache(fallback){
  var cache = {};

  this.get = function(id){
    if (!cache.hasOwnProperty(id)){
      cache[id] = fallback.apply(null, Array.prototype.slice.call(arguments, 1));
    }
    return cache[id];
  }
}

var copy = (function(){
  var cache = new Cache(createPrototypedFunction);

  function createPrototypedFunction(parent, name){
    var f = eval('function '+name+'(){};'+name);
    f.prototype = parent;
    return f;
  }

  return function(parent, name){
    return new (cache.get(name, parent, typeof name==='undefined'?'Foobar':name));
  };
})();
answered 2011-05-06T08:03:38.737

Your Answer