I'm having trouble with a function that I'm calling multiple times. Every time I call it, it should receive fresh data (even if its the same as earlier) but somehow, next call to the function will result in what was expected output from the first call to the function.
The code:
$.calc=function(arrayName){
console.log(arrayName);
for(i=0;i<arrayName.length;i++){
if(i==2){
arrayName[i]="";
}
}
}
var arr=new Array();
arr[0]="saab";
arr[1]="saab";
arr[2]="saab";
arr[3]="saab";
arr[4]="volvo";
arr[5]="volvo";
//First run
$.calc(arr);
//Second run
$.calc(arr);
If you run the code (http://jsfiddle.net/76bme/) and open console logger/devtools you can see that I'm printing out the contents of the array that I passed along with the function, BEFORE doing anything with the array.
Next time I call the function, I pass the same array (arr) to the function as in the first call to the function, so I expect that console.log in the beginning to print out the same contents from the array. But now the array holds everything as earlier except at index 2 where I modified it to "" AFTER I printed it out with console.log. If it was the other way around I would get it (having console.log after the for-loop) but now I'm just confused!?
So what am I doing wrong?
That is because arrayName is a reference to your array object. So when you change something in that object, your arr is affected aswell. If you don't want this behaviour, you need to "create a copy" of your array :
$.calc=function(arrayName){
console.log(arrayName)
var myArr = Array.prototype.slice.call(arrayName); //Just here!
for(i=0;i<myArr.length;i++){
if(i==2){
myArr[i]="";
}
}
}
Fiddle : http://jsfiddle.net/76bme/5/
Change
console.log(arrayName);
to
console.log(arrayName.join(";"));
And you will see what you expect. The console [depending on state] does not show a snapshot of the object/array at the current time it was logged, sometimes it stores a reference to it so it will have the current values.
Related
I have a function
function recursiveDivisionWrap(width, height, colStart, colEnd, rowStart, rowEnd)
in which i have an empty set
let blockedNodes = new Set();
inside this function I have another, recursive function
function recursiveDivision(width, height, colStart, colEnd, rowStart, rowEnd)
On each call of the recursiveDivision function i update a blockedNodes set by adding value:
for (let i = colStart; i < colEnd; i++) {
blockedNodes.add(`c${i}r${wallStart}`);
}
If I console.log blockedNodes set inside recursiveDivision function, I'm getting desired result, for example:
Set(43) {'c0r7', 'c1r7', 'c2r7', 'c3r7', 'c4r7', …}
However when I console.log blockedNodes set inside recursiveDivisionWrap and not in recursiveDivision, I'll get comma separated object:
c0r7,c1r7,c2r7,c3r7,c4r7,c5r7,c6r7,c7r7,c8r7,c9r7,c9r0,c9r1,c9r2,c9r3,c9r4,c9r5,c9r6,c8r0,c8r1,c8r2,c8r3,c8r4,c8r5,c8r6,c3r0,c3r1,c3r2,c3r3,c3r4,c3r5,c3r6,c4r6,c5r6,c6r6,c7r6,c4r1,c5r1,c6r1,c7r1,c4r5,c5r5,c6r5,c7r5
I've also tried with array and the result was the same.
Why doesn't it return Set(43) {'c0r7', 'c1r7', 'c2r7', 'c3r7', 'c4r7', …} if the blockedNodes set is defined outside the recursiveDivision function and inside recursiveDivisionWrap and why does the inner recursiveDivision function returns correct set?
I would appreciate any help in finding answer to that question.
This behaviour has nothing to do with the place where the output is made, but how the output is formatted.
You have these statements:
console.log(blockedNodes);
And:
console.log(`Is this a set? ${blockedNodes}`);
And:
let ecie = Array.from(blockedNodes);
console.log(`Is this an array? ${ecie}`)
They don't do the same thing.
console.log(blockedNodes) leaves the rendering to the console API, which may provide additional information, like the name of the constructor of the object (Set in this case), the number of items this collection has, ...etc. It may even add user-interface controls to expand/collapse the contents of the collection and potential nested data structures.
console.log(`Is this a set? ${blockedNodes}`) will implicitly call blockedNodes.toString() in order to produce the string. Unless toString has been overriden, that will render as [object Set], and so the total output will be "Is this a set? [object Set]".
console.log(`Is this an array? ${ecie}`) will also call the toString method, but this time on ecie, which is an array (as that is what Array.from returned). The toString method on arrays produces a comma separated list of the values, which explains the output you mentioned.
Suppose there's an array called '_arr' from which I remove an item. Before removing though I log it to console. Problem is that log shows the array as if the item is removed already. I have reviewed data system in Polymer Documentation and still scratching my head.
Am I missing something on how data system works or I should be looking somewhere else for the cause?
EDIT: _arr is an array of strings and I am passing an event like:
this.fire('rmv-item' , {item: 'item content which is string'});
Here's the code
_removeItemFromArr: function(e) {
const index = this._arr.indexOf(e.detail.item) ;
console.log('array before remoivng item:' , this._arr , index); //item doesn't exist
if (index>-1) { this.splice('_arr' , index, 1 }
console.log('array after removing item: ' , this._arr , index); //item doesn't exist
},
The problem is that things are doing exactly what you say: the console logs the array, it most emphatically does not log the array "as it was at some specific time in the past", it logs the array as it is when log actually runs. And because the logging operation is not synchronous, by the time it actually writes the crosslinked reference and symbol-table-linked data to the browser console, you already removed the data from the array, so what you see is what console.log sees when it actually kicks in.
If you want a true snapshot of what your array ways "when you call log", don't log the array, log a copy of the array, which is guaranteed to generate synchronously using something like slice():
const index = this._arr.indexOf(e.detail.item);
console.log(`array before removing item at [${index}]: ${this._arr.slice()}`);
And job's a good'n.
I have found that when using console.log on a nested object the result seems to print after subsequent operations have performed, but only when logging an object with a depth of at least two.
Consider the following example:
function addNumbers(data) {
data.container.firstNumber++
console.log(data); // 3
data.container.firstNumber++
}
var numberData = {
container : {
"firstNumber": 1
}
};
console.log(numberData); // 3
addNumbers(numberData);
I assumed that with this example I would see numberData printed with the values 1 and then 2. In actuality, the value is 3, 3. My first thought was perhaps there is some race condition here where the values changes before the log operation can complete, but if you add more specific references to the object, you will get the value that matches the console.log's position in the code like this:
function addNumbers(data) {
data.container.firstNumber++
console.log(data.container); // 2
data.container.firstNumber++
}
var numberData = {
container : {
"firstNumber": 1
}
};
console.log(numberData.container); // 1
addNumbers(numberData);
Why doesn't the variable evaluate to its value relative to the position of the console.log in the first example, but does in the second example?
relevant fiddle
Most browsers only fetch the properties of an object logged to the console when you expand the object -- and often note this in a tooltip next to the object reference.
They also tend to only expand the object the first time and cache from then on, so the console is not a reliable way to inspect objects.
To get around this, browsers offer a watch panel that will update more frequently and can be used with breakpoints or stepping to get the current state of an object repeatedly.
I am having trouble understanding how to call specific array values:
I have commented out the questions in the code. Please take a look and let me know why the array produces one result within the function, while producing a different result outside of it. To run the code, please use a website like repl.it
var passengers = [ ["Thomas", "Meeks"],
["Gregg", "Pollack"],
["Christine", "Wong"],
["Dan", "McGaw"] ];
var results = passengers.map(function (array) {
// The following prints out the first names--the entire first column. Why?
console.log(array[0]);
});
console.log(); // Just empty space
// Why is the following only printin the first row of passengers (which it should), but the array[0] printed out the entirety of the first column?
console.log(passengers[0]);
You have an array of arrays, so when you call map here:
var results = passengers.map(function (array) {
// The following prints out the first names--the entire first column. Why?
console.log(array[0]);
});
It's looping through the outer array. The parameter that gets passed into the function is the element of the array that you're looping through, in this case, the inner array. So the console.log(array[0]) is printing the first element of the inner array.
In other words, this code is roughly equivalent to:
console.log(passengers[0][0]);
console.log(passengers[1][0]);
console.log(passengers[2][0]);
console.log(passengers[3][0]);
Notice that in this example, I'm only iterating through the outer array (the first index). The inner array index stays at zero.
But later where you have
console.log(passengers[0]);
It's simply printing the first element from the outer array, which is the entire first inner array.
Further Reading
Array
Array.prototype.map()
How can I make this work:
q = {}
q[0] = new Array()
q[0].push(function()
{
console.log("whatup")
})
q[0]() // currently prints "q[0] is not a function"
Of course, it shouldn't execute until I call it. I tried nesting it inside another function as a return value, but nothing works :(
You have a multidimensional array, but you're only accessing the first dimension at the end (which is another array). Try q[0][0]().
The problem is that the value in q[0] is the new Array() that you assigned to it -- not a function.
These lines:
q[0].push(function()
{
console.log("whatup")
})
will put the function as the first element of the new Array you assigned to q[0] in the second line. So instead of this:
q[0]() // currently prints "q[0] is not a function"
You're really wanting to do this:
q[0][0]()
Your code should work but you're calling the array. To call the function you need to do
q[0][0]()