You're trying to assign something to photos[a]["url"], photos[a]["caption"], etc., but photos[a] doesn't exist yet. photos is an empty Array at first, so you have to set photos[a] to something first. Since you want to use string keys ("url", "caption", etc), this something should be a plain object (the javascript equivalent to php associave arrays) (or a Hash if your code base allows it). Then you can use a literal object construct to simplify your function, and Array#push to get rid of the unnecessary a:
var photos = [];
$("#photos img").each(function(img) {
photos.push({
url: img.src,
caption: img.alt,
background: img.style.backgroundColor
});
});
Also, make sure that this is actually your img element. Some each implementations will set this to the global object in your case.
edit: ok, it looks like jQuery.each automatically sets this to the iterated element, but doesn't wrap it in jQuery-goodness, so you have to either wrap this in $() or use plain DOM (I used the latter in my example).
edit2: anyway, using this is kind of strange since the callback function passed to each receives an argument. Might as well use this argument (renamed).