chrome debugger inconsistency in object data - javascript

I don't understand how to interpret this debug data. I do a console.log of my object, and on the summary-line that appears in the console I am shown windows: array[0] but if I expand the object, I am shown that windows is an array of 2 items.
Which is the correct one?
My code seem to run on the summary version, ie. windows array being empty.
Does anyone know what my problem is - why is the object presented in an inconsistent way?

The object is being mutated between when you print it and when you view it. When it's initially logged, it's empty but by the time you open it, 2 items have been added.
var obj = { arr: [] };
console.log(obj); // Will say { arr: Array[0] }
obj.arr.push(1); // Open it up in the console after this
Basically, the dev tools print a string that's representative of it's state at the time of the log but it stores a reference to the object in the console itself.

Related

Console setting for displaying hex numbers

I've just noticed that when logging a data structure which contains a hexadecimal string value to the console, it output's the field as 1, instead of the string value. This is happening in Chrome and Safari.
At the top of the screenshot, you can see an object being logged, this object has an '_id' field, this string is a MongoDb ObjectId, in a nutshell, it's a hexadecimal string.
You can see at the top of the screenshot that the _id field contains a string but when it's (the object) value is being printed (the expanded view), it's being displayed as (Number) 1.
The second log is me console.log'ing the value explicitly, i.e.
//Where obj is the object being logged in the screenshot.
console.log(obj.data._id);
Unsure exactly what's happening here, I can't see how the value being logged would be output as Number 1, that is not the base 10 value of the hexadecimal string, the console is surely making some assumption about the value, and processing it, unsure exactly what's going on there though.
So my question is
Why is 1 being printed here?
Without knowing what else has happened to the object after it's been sent to the console, I'm assuming what you are seeing here is how Chrome's console log keeps a reference to the object, it doesn't hold a snapshot at the time of console logging, but a live reference to the object.
Below is a simple example.
Open up Chromes console,. you will see {x: "one"}, but when you expand the object you will see x: 1 and not x: "one"..
var a = {
x: "one"
};
console.log(a);
a.x = 1;

Why javascript cannot access some object by key?

I have a JavaScript Object named "userinfo" (it stored some user's info). And I want to access value by key in it. For all the keys I can success get, except one key named "auths". And then I print it in console by console.log(userinfo), it shown as well. And while I traversal it Object, the key don't show again...
And then I click the option "Store as global variable" in Chrome debug console. And not when I try to access, it works well.
Here it's my code and debug's screenshot.
console.log(userinfo);
for (var key in userinfo){
console.log(key + " = " + userinfo[key]);
}
Because here some my really personal informations in it, I produced this picture.(Position I've printed "hide info").
I want to know why the code working not well, and how can I access the info stored in key "auths".
Thanks!
console.log is deceiving. It's printing a "live" object. If object is altered after it's been logged, the log will update (you'll see the new property when you expand the object in the log). Naturally, this doesn't apply to the temp strings you build there with concatenation. So yes, I'd bet 10 bucks that the object does not indeed have auths property at the time of printing. It is added later.
Observe this in action (look in browser's console)
var myobj = { foo: 1 }
console.log(myobj);
myobj.bar = 2;

Javascript: splice strange behavior

I'm running a splice on an array like this, where the array has 5 elements:
array.splice(3, 0, newObj);
The splice doesn't work and I still have 5 elements.
When I debug it in Chrome with console.log I see an array of six objects, but when I open the array I see five elements (see pic below). What does this mean?
You're inserting a new object into that array -> newObj
For example, if you run this in Chrome console, works fine :
function aHandler (){
var a = [{1:1},{1:2},{1:3},{1:4},{1:5}];
a.splice(3,0,{1:20});
console.log(a);
}; aHandler();
Even if you insert null or undefined console.log should show you the right object.
So, maybe you modify the object somewhere between splice and console.log

Javascript Array logging confusion

I have noticed something that I cannot understand at all. I am doing something really simple in JavaScript:
var a = [1,2,3];
console.log(a.push(4));
console.log(a);
console.log(a.push(5));
I would expect the console to log: 4, [1,2,3,4], and 5 as described here for example.
The catch is that the actual console output looks like: 4, [1,2,3,4,5], and 5
See: http://jsfiddle.net/HknMF/
What on earth makes the 5 appear in the second log output?
EDIT: fwiw here's a screenshot of Firebug showing both behaviors: http://i.imgur.com/fwAK3.png
​
The console in some browsers uses a reference to the array/object, so when you inspect it and the object changed after the console.log() call you'll see the changed object.
In Firefox this also happens for objects, but not for arrays which are displayed inline anyway:
>>> var a = [1,2,3]; console.log(a.push(4)); console.log(a); console.log(a.push(5));
4
[1, 2, 3, 4]
5
Especially for objects that do not contain functions a quick workaround is either cloning them (log $.extend({}, yourObject) if you have jQuery) or logging their JSON string version (then you lose the nice object view and just get a plain string though). An array can easily cloned (shallow copy!) using a.slice(0)
Dependent of the Browser either your live array gets logged (Chrome) or A string representation (Firefox).
A shallow copy is sufficient to prevent that. Use:
console.log( a.slice(0) );
for that.

Array containing objects has wrong length

I have an array like:
errors = [ {...}, {...}, {...} ]
It's an instanceof array, yet it only returns 1 for .length?
Relevant code:
if(data.error){
errors.push({'element':ele,error:data.error});
}
//Above is looped a few times and there are N number of errors now inside
console.log(errors) //Returns 2+ objects like {...}, {...}
console.log(errors.length) //Returns 1
For Uzi and Muirbot, here's the errors array:
[
Object
element: b.fn.b.init[1]
error: "You must enter "example" into the field to pass"
__proto__: Object
,
Object
element: b.fn.b.init[1]
error: "Crap!"
__proto__: Object
It is correct, this code:
var errors = new Array();
errors.push({'element':'ele', error:'data.error'});
...adds ONE object to the array. The object has two properties.
It's possible your code is executing in an order other than what you're expecting. ie, when you log both errors and errors.length, errors does contain only 1 object. But after that you are adding to the errors array, and only after that are you looking at the console. At that point you could see a larger array in errors for two reasons - first, your actual code isn't logging errors but some object that contains errors. In that case the console display is live, and will show you not what was in errors at the time, but what is in it now. Alternatively, the console could just be taking some time to log errors.
Without more code I can't be sure if this is the case. But you could verify it by replacing console.log(errors); with console.log(errors[1]);. If errors is really only 1 long at the time, it will log undefined.
The problem was that Chrome's Web Inspector's console.log is an async event. So, the length was a property lookup so it gave that back instantly, but the object with two items inside was held off until the rest of the events had fired.
In the future I, and others with this issue, should use debugger; instead.
is it an Array object or something that resembles it?
arrays do work:
> a = [{a:1}, {b:2}]
[Object, Object]
> a.length
2
you'll have to provide more code.
and now that you've provided the relevant code, the correct answer is what Steve Wellens said (which was downvoted, by the way).
Array.push adds a single element, objects may have more than one key but they're still a single object so your real case was different from your original example, which of course works.
another possibility:
> a = []
[]
> a.length = 2
2
> a
[]
> a.length
2
> a instanceof Array
true

Categories

Resources