Checking for memory leaks in data structures I'm looking for a code review for my JavaScript code that checks if there is any memory leaks in data structures. Please include constructive criticism, as well as details on what I can do to make this code more efficient.

// memoryleak.js
// (C) 2014 Kyle Maune
// checks for memory leaks in data structs

MemoryLeak = {

  uniq_id: (new Date()).getTime(),
  checked: 1,
  is_seen: [],

  checkLeaks: function(obj) {
    var self = MemoryLeak

    if(!obj || (typeof obj == 'function') || self.checked &gt; 20000)
      return;

    if ((self._isArray(obj) || self._isObject(obj))) {
      if (self._isArray(obj)) {
        self._logTooBig(obj, obj.length)
        for (var i = 0; i &lt; obj.length; i++) {
          self._checkIfNeeded(obj[i])
        }
      }
      else if (self._isObject(obj)) {
        self._logTooBig(obj, self._keys(obj).length)

        for (var key in obj) {
          self._checkIfNeeded(obj[key])
        }
      }
    }
  };

  _checkIfNeeded: function(obj) {
    if (!obj)
      return;

    var self = MemoryLeak;
    self.checked++

    if ((self._isArray(obj) || self._isObject(obj))) {
      if(obj.__leaks_checked == self.uniq_id)
        return;
      obj.__leaks_checked = self.uniq_id

      setTimeout(self._partial(self.checkLeaks, obj), 5);
    }
  };

  _logTooBig: function(obj, limit) {
    if (limit &gt; 200) {
      console.log('Object too big, memory leak? [size: ' + limit + ']')
      console.log(obj)
      console.log('-------')
    }
  };

  _keys: function(obj) {
    var rval = [], prop
    for (prop in obj)
      rval.push(prop)
    return rval;
  };

  _isArray: function(obj) {
    try {
      return obj instanceof Array
    }
    catch(e) {
      return false;
    }
  };

  _isObject: function(obj) {
    return (typeof obj == 'object')
  };

  _partial: function(fn) {
    var args = Array.prototype.slice.call(arguments)
    args.shift()
    return function() {
      var new_args = Array.prototype.slice.call(arguments)
      args = args.concat(new_args)
      return fn.apply(window, args)
    }
  }
}
This code


if ((self._isArray(obj) || self._isObject(obj))) {
  if (self._isArray(obj)) {
    self._logTooBig(obj, obj.length)
    for (var i = 0; i &lt; obj.length; i++) {
      self._checkIfNeeded(obj[i])
    }
  }
  else if (self._isObject(obj)) {
    self._logTooBig(obj, self._keys(obj).length)

    for (var key in obj) {
      self._checkIfNeeded(obj[key])
    }
  }
}



should be reduced, remove the outside if statement

  if (self._isArray(obj)) {
    self._logTooBig(obj, obj.length);
    for (var i = 0; i &lt; obj.length; i++) {
      self._checkIfNeeded(obj[i]);
    }
  }
  else if (self._isObject(obj)) {
    self._logTooBig(obj, self._keys(obj).length);

    for (var key in obj) {
      self._checkIfNeeded(obj[key]);
    }
  }


There is no need for it. 



Also some of your one liner blocks make use of Curly Brackets and some do not,  this is confusing when put together with your 2-space indenting instead of 4-space indenting.  don't worry about space when writing your JavaScript, use all the characters that you need to be able to maintain the code properly, don't Minify until you are completely finished with the code.

Especially when nesting if statements


if ((self._isArray(obj) || self._isObject(obj))) {
  if(obj.__leaks_checked == self.uniq_id)
    return;
  obj.__leaks_checked = self.uniq_id

  setTimeout(self._partial(self.checkLeaks, obj), 5);
}



you should use brackets and proper indenting to make it clear what is going on

if ((self._isArray(obj) || self._isObject(obj))) {
    if(obj.__leaks_checked == self.uniq_id){
        return;
    }
    obj.__leaks_checked = self.uniq_id;

    setTimeout(self._partial(self.checkLeaks, obj), 5);
}


This is also one that almost confused me as well


_keys: function(obj) {
  var rval = [], prop
  for (prop in obj)
    rval.push(prop)
  return rval;
};



I would write it like this (and don't forget the ;)

_keys: function(obj) {
    var rval = [], prop;
    for (prop in obj){
        rval.push(prop);
    }
    return rval;
};




I just realized how many times you left out the semi-colons after a line of code,  this is a very bad habit to fall into.

Always remember your semi-colons!

There are places where I don't think the code will run correctly because you don't have semi-colons to tell the browser that you have ended the command.