2

I know arrays in javascript are a bit special, compared to other languages, but I don't really get this behaviour, or what's going on here.

I'd like to know why it happens and why I don't get an empty array:

function setupWindowProgBar(settings, window, palette, arr){
    console.log('start');
    console.log(arr);
    if(typeof arr == 'undefined'){
        var arr = [];
    }
    console.log(arr);
    console.log('stop');
    var arrLen = arr.length;
    arr[arr.length] = createProgBar('master', 'bg', window, 0, settings.fillColor, settings.strokeColor, settings.textColor, palette, 'percent', settings.reqType, settings.sourceType, settings.sourceTarget, settings.sourceId);
    return arr;
}

produces this in the console:

start
undefined
[]
    0:
    barType:"master"
    bgcolor:"#12181f"
    curVal:160
        data:
        all_goals:160
        cost_hours:160
        cost_hours_spent:0
        cost_money:31610
        cost_money_owned:0
        parentObj:"progBar"
        progress_goals:5
        recurring:"no"
        wanted_timer:"2018-03-26 05:19:33"
        __proto__:Object
    fill:"#255f6f"
    height:59
    maxVal:5
    maxWidth:168
    sectionHeight:59
    stroke:"#7b9dac"
    text:"3%"
    textColor:"#dee5ed"
    textOpt:"percent"
    width:200
    x:33
    y:81
__proto__:Object
height:100
text:"omanko"
length:1
__proto__:Array(0)
stop

I do reckognize the objects in here, but it's not from global pollution as far as I can tell - console.log(window.arr) says that there are no global variables named arr, and I haven't modified the prototype.

Surely, that shouldn't effect a new array declaration anyway?

5
  • That should not happen, since arr should be an empty array at the point you log it, not a strange object. I'm sure you've omitted crucial parts of your code. Commented Apr 15, 2018 at 4:54
  • I agree, it shouldn't happen - will add the entire function for clarity Commented Apr 15, 2018 at 4:56
  • It just makes no sense to me at all Commented Apr 15, 2018 at 4:58
  • no, @Tigger it IS an array, what I want to know is why arr[0] is populated with a nested object. Where does this pollution come from, if not from the global scope? Commented Apr 15, 2018 at 5:04
  • the console lies - in chrome console (if you're using chrome), it even tells you that the displayed object is evaluated "just now" - so, in the console you see arr[0] as the result of createProgBar - despite console.log appearing earlier Commented Apr 15, 2018 at 5:11

3 Answers 3

3

This behaviour isn't limited to arrays, any object behaves this way in the console

What you are seeing is the result of console in all browsers "lying" to you

if you console.log(anyobject) and inspect that object in the console, what you will see is current anyobject - not what it was when console.log was executed

var obj = {}
console.log(obj);
obj.test = 1;

var arr = [1];
console.log(arr);
arr.push(2);

Now, if you open the developer console, click on the Object, you'll see test:1

Look at the array in the console - it is output as [1] ... yet, click on the array you see both elements

Note: chrome developer console does at least hint at the fact that it's lying to you - there's a blue i, if you hover (or click, can't recall, don't use Chrome often enough) you'll see a message saying that the value shown is evaluated just now

Sign up to request clarification or add additional context in comments.

6 Comments

That's the answer I guess.
But I see another weird behavior in Chrome. var obj; console.log(obj); obj = {test: 1}; This code prints undefined rather than obj's current value
yes, because it is undefined - and a new object is assigned, therefore the console won't show this new object "later" - so, there's actually nothing weird about that at all
Ah! Okay. Got it. If I write var obj = {}; console.log(obj); obj.a = 2, I guess what it is probably doing is that it is maintaining a reference to the obj object and outputs the current value of that object.
yes, that is exactly the code I posted, except you used a property called a and I used test ... test isn't something special
|
0

The issue is when you call console.log(arr) it puts a reference to the array in the console that gets dereferenced when you "open" it (click on the arrow) so it will display changes that are made later in code. Use console.table(arr) or console.log(JSON.stringify(arr)) instead.

Here is a snippet from MDN

Please be warned that if you log objects in the latest versions of Chrome and Firefox what you get logged on the console is a reference to the object, which is not necessarily the 'value' of the object at the moment in time you call console.log(), but it is the value of the object at the moment you click it open.

Comments

0

arr is a parameter to your function already, and it is not undefined. var gets hoisted, so to the interpreter, your current code actually looks something like:

function setupWindowProgBar(settings, window, palette, arr){
  var arr; // **does not reassign the parameter**
  console.log('start');
  console.log(arr);
  if(typeof arr == 'undefined'){
    arr = [];
  }
  console.log(arr);
  console.log('stop');
}

You should never be declaring a variable whose name is already scoped to the block/function you're using it in.

If arr actually isn't defined in the argument, then it will be assigned to an array on the line arr = [];, but at least on Chrome, that empty array will not necessarily be printed at the time you console.log it.

console.log(arr); does not necessarily immediately display the arr - depending on your browser, it may only be populated in your console after you open your console, after this line has run:

arr[arr.length] = createProgBar('master', 'bg', window, ...

9 Comments

just one quick followup question though, how come the first console.log(arr); before the if statement returns "undefined"?
@DanielBengtsson Exactly what I am wondering. The first console.log(arr) prints undefined.
arr is a parameter to your function already, and it is not undefined what if it is? i.e. you call using setupWindowProgBar(settings, window, palette)
I added this: console.log('test'); in the if statement - it DOES run.
@Ooops, missread - yes, you are correct - sometimes it is. I know the logic is messed up, and I am refactoring the code now, and I don't have a problem fixing it - I am more so interested in WHY it happens so I know how to use/avoid it in the future.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.