views:

77

answers:

5

In Javascript, if an object has lots of properties that are functions:

var obj = { foo: function() { ... },
            bar: function() { ... },
              ...
          }

then how can you get an array of names of those functions? That is, an array

["foo", "bar", ... ]

thanks.

+5  A: 
var names = [];
for( var k in obj ) {
   if(obj.hasOwnProperty(k) && typeof obj[k] == 'function') {
      names.push(k);
   }
}
Jacob Relkin
interesting, how come push will not push a function reference into the array but will push the name of the function?
動靜能量
`for in` loops over property names, not the actual properties. So if you want to reference each property, you would use `obj[k]`.
Casey Hope
so what if there is only 1 function inside, still have to use a "for in" loop to achieve this purpose? is there another way if "for in" loop doesn't exist?
動靜能量
to enumerate properties you have to use `for..in`. There is no other *correct* way.
Sean Kinsey
+3  A: 
var functions = [];
for (var prop in obj) {
    if ((typeof obj[prop]) == 'function') {
        // it's a function
        functions.push(prop);
    }
}
ob1
This will not work unless you use **lower case** "function"
Jacob Relkin
Fixed. thanks :-)
ob1
+3  A: 

Edit: I've slightly misread the question, you want to extract the names of only the properties that are function objects:

function methods(obj) {
  var result = [];
  for (var prop in obj) {
    if (obj.hasOwnProperty(prop) && typeof obj[prop] == 'function') {
      result.push(prop);
    }
  }
  return result;
}

var obj = {
  foo: function() { },
  bar: function() { },
};

methods(obj); // ["foo", "bar"]

I'm using the hasOwnProperty method, to ensure that the enumerated properties in fact exist physically in the object.

Note that this approach and all other answers have a small problem IE.

The JScript's DontEnum Bug, custom properties that shadow non-enumerable properties (DontEnum) higher in the prototype chain, are not enumerated using the for-in statement, for example :

var foo = {
  constructor : function() { return 0; },
  toString : function() { return "1"; },
  valueOf : function() { return 2; }
  toLocaleString : function() { return "3"; }
};

for (var propName in foo ) { alert(propName); }

The object foo clearly has defined four own properties, but those properties exist in Object.prototype marked as DontEnum, if you try to enumerate the properties of that object with the for-in statement in IE, it won't find any.

This bug is present on all IE versions, and has been recently fixed in IE9 Platform Preview.

CMS
+1 for mentioning hasOwnProperty, but I believe Jian was after just the functions, not all the properties.
Dan F
+1  A: 

To complete other answers: you can also use instanceof:

var obj = { foo: function() { ... },
            bar: function() { ... },
              ...
          },
    fnArr = [];

for (var label in obj){
  if (obj[label] instanceof Function){
     fnArr.push(label)
  }
}
KooiInc
+1  A: 

With ES5:

var obj = {
    foo: function() {},
    bar: function() {},
    baz: true
};

function getMethods(object) {
    return Object.keys(object).filter(function(key) {
        return typeof object[key] == 'function';
    });
}

getMethods(obj); // [foo, bar]

Object.keys(<object>) returns the names of all enumerable properties of an object as an array, of which the non-functions are filtered out.

Example - works on Chrome release and nightly builds of Webkit and Tracemonkey (Firefox).

Anurag