简体   繁体   中英

JavaScript: Can't access array in object

I'm experiencing extremely strange behavior when accessing a property of an object.

Running this code:

console.log(myObj);
console.log(myObj.items);
console.log(myObj);

I get this output in the console:

在此处输入图片说明

How could this possibly happen?

console.log , during execution, outputs a string representation of the value in the console. Depending on Chrome's mood, it might show something [object Object] or something like Object {} . That doesn't matter.

Now note the little blue i beside it. What it means is that the object has been modified between the time it was logged and the time you expanded it in the console, and it now shows the current value (with the 2 items), not the value during console.log 's execution (no items). You can actually hover on the blue i to get the explanation.

To replicate the issue, open the console and run this snippet:

 var obj = {arr: []}; console.log(obj); console.log(obj.arr); console.log(obj); // by this time, you see 2 object logs, 1 empty array // (representation differs from time to time) // > Object // [] // > Object obj.arr.push(1,2); // when you try to expand the objects, an array of 2 items magically appear // but you still see the empty array ([]) in the log. 

This behavior differs across browsers. As far as I remember, Firebug outputs a serialized version when console.log executes, hence this doesn't happen there.

Debugging the code

To debug this kind of code, you have several options:

  • The quickest way is to log the stringified version of the object using JSON.stringify , like console.log(JSON.stringify(obj)) ;

  • The best way is to add a breakpoint via the Sources tab. Browse to your file in the Sources tab of the Dev Tools, and add a breakpoint in that position. Run your code, and it will pause at that point. Use the Scope panel to inspect the variables.

  • If you can't reach the code using a breakpoint (probably run using eval or injected in the console), you can use the debugger; statement. Just put it in the code at that position. Run the code and it will pause when it reaches the statement. Use the Scope panel in Sources tab to inspect.

您可以查看要检查的对象的JSON表示形式,可以执行以下操作:

console.log(JSON.stringify(myObj, null, 2));

With so little information, I can only assume you're dynamically populating the items property, making it empty when the 2nd console log runs.

Now you're wondering why it is there in the 1st console log: the console doesn't show the object properties that were there at the time the object was logged, but rather at the time the object entry was expanded in the console, so it could be that the items were populated after your 2nd console log and before you expanded the 1st one. Try logging the object as a string or a JSON to see its actual state at the time the console log was run.


Bottom line: object properties in the dev console get updated only when you expand the object entry (when you click the arrow) so you're not seeing the actual representation of the object from the time it was logged.

Here's a simple demonstration - see how it can even turn from an array into a string:

 var obj = {p: []} console.log(obj); setTimeout(function(){ obj.p = "I'm not even an array!"; }, 1000); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM