This question already has answers here:
forEach on array of undefined created by Array constructor
(5 answers)
Closed 5 years ago.
When running this code I expect this to log 5 undefined's. However I only see two. It appears that JavaScript only logs undefined's that you define yourself.
var a = [];
a[0]=undefined;
a[4]=undefined;
a.forEach((i)=>console.log(i))
This logs:
undefined
undefined
Wouldn't you expect it to log 4 undefined's?
Here is a codepen.
Quoting mdn:
forEach method executes the provided callback once for each element present in the array in ascending order. It is not invoked for index properties that have been deleted or are uninitialized (i.e. on sparse arrays like your example),
From what I remember the lo-dash forEach method is different it behaves like you would expect.
It is because of forEach loop.
forEach() executes the provided callback once for each element present in the array in ascending order. It is not invoked for index properties that have been deleted or are uninitialized (i.e. on sparse arrays).
--Source MDN
Example Snippet:
var a = [];
a[0] = undefined;
a[4] = undefined;
a.forEach(function(i) {
console.log(i)
})
for (var i = 0; i < a.length; i++) {
console.log(a[i] + " from for loop");
}
so javascripts arrays are basically just special obejcts that have integer keys (there are some minor differences). so you defined an object with 2 keys values. 0: undefined and 3: undefined. since theres only 2 things in the array, it only prints 2 undefineds.
Related
This question already has answers here:
How can JavaScript arrays have non-numeric keys?
(2 answers)
How do I loop through or enumerate a JavaScript object?
(48 answers)
Closed 4 months ago.
I am going crazy here, I have an associative array as seen below which is defined after the page finishes loading. However Array.forEach is returning undefined and I have no idea why. The array is most definitely populated during the loop. Can anyone give me any ideas? Also doesn't work with JQuery's $.each
Arrays are usually a mapping of index (integer from 0 to 232 − 2, inclusive) to value. In your case you've treated the array as a dictionary e.g. key (string) to value.
You've probably done something like this:
members = new Array();
members['animerox1213'] = 'Ashima';
JavaScript allows this, after all it is still an object:
typeof members === 'object'
But instead of adding a value to the array, you've actually set a non-numeric property on the object called animerox1213. That is not how an array should be used and we can observe this by checking the size:
members.length === 0;
Consequently, forEach does not do anything as it considers it an empty array.
That said, it is enumerable with for…in as it's still just an object (with enumerable properties):
for (m in members) {
console.log(m, members[m]);
}
Consider using just an object e.g. members = {} or Map. Note especially the section Objects vs. Maps.
This question already has answers here:
How length property of an array works in javascript?
(7 answers)
Is the JavaScript Array.length property a function or a simple variable?
(7 answers)
Array.length is a property not a method, but how .length is work like a method?
(4 answers)
Closed 3 months ago.
My question is if I use an array like this,
var arr1 = [1, 2, 3, 4];
console.log(arr1.length); // 4 (Expected)
If I update the length property, the array gets updated too.
arr1.length = 0;
console.log(arr1); // []
I'd like to know how this is being done (the internals)?
Also, I'm not sure if getter and setter methods of the property length (that are ways to run a function if the property gets accessed or set) are used here. I think they're not.
If it's being used, length should not be visible directly when I expand the array in the browser console. But we get the length directly without running any functions.
The console when I use get/set for a property of an object,
Getting the value of length property directly without running any functions,
This question already has answers here:
Why can't I use Array#includes for a nested array?
(5 answers)
How to compare arrays in JavaScript?
(61 answers)
Closed 3 months ago.
TL;DR: the JavaScript code below returns false where I'm expecting a true, what's the best workaround?
console.log([['a']].includes(['a']))
I'm pushing arrays into arrays (to work with google sheets ranges in apps script, but the behaviour is the same in regular JavaScript).
I'd like to check if my parent array (let's call it [['a']]) contains specific child array (such as ['a']).
Unfortunately array.includes() doesn't seem to work as expected when the parameter is an array. (the code above returns false when it should be true as far as I know)
Am I missing anything? What do you think would be the best workaround?
The problem is array comparison.
console.log(['a'] == ['a']); //false
As the .includes() method loops through the array on which it is being called, it checks each element to see if it is equal to the value being tested for, until it finds a match, or checks every element of the array. As you can see above, when the value being tested is an array, it will not work.
A work around would be to write your own .includes() function in which you loop through all the child arrays in the parent array, and for each child array, loop through every element, testing whether it is equal to the corresponding element in the test array. You can use the .every() method for this.
let array = [['a']];
function includesArray(parentArray, testArray) {
for (let i = 0; i < parentArray.length; i++) {
if (parentArray[i].every(function(value, index) { return value === testArray[index]})) {
return true;
}
}
return false;
}
console.log(includesArray(array, ['a'])); //true
console.log(includesArray(array, ['b'])); //false
One quick alternative is to compare the JSON strigified arrays instead of comparing arrays directly.
console.log([['a']].map(x => JSON.stringify(x)).includes(JSON.stringify(['a'])))
This question already has answers here:
Length of a JavaScript object
(43 answers)
Closed 6 years ago.
I am new to JavaScript objects so please bear with me.
This is my JavaScript:
var dragSources = {
elementSources: {
squareSource: document.getElementById('squareSource'),
circleSource: document.getElementById('circleSource')
},
ifDragSource: function(elem) {
console.log(this.elementSources.length);
}
};
If you look at console.log(this.elementSources.length); you can probably tell that I am trying to get the length of the elementSources property. However, it returns undefined. What am I doing wrong?
It's an object, not an array, therefore it doesn't have a length property.
You could use Object.keys(this.elementSources).length to get the number of keys.
The .keys() method essentially returns an array of the object's keys.
In this case, Object.keys(this.elementSources) returns:
["squareSource", "circleSource"]
Then we are just getting the length of that array, which is 2.
var dragSources = {
elementSources: {
squareSource: document.getElementById('squareSource'),
circleSource: document.getElementById('circleSource')
},
ifDragSource: function(elem) {
console.log(Object.keys(this.elementSources).length);
}
};
dragSources.ifDragSource(); // 2
Technically if you need the length property in a code you have to store the length value directly in the object.
Using Object.key function decreases the code efficiency .
every time you invoke that function to access that value you have to re-run the same function again and again.
in order access to the length property in a js array, the BIG O is always equal to 1.
because when you update the array the length property would be updated consequently
But in that case the big O would be in the size of the Object and (O) = n
This question already has answers here:
Length of a JavaScript object
(43 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I looked at similar questions and tried Object.key(patientList).length but it returns 0. I was recommended to use callbacks and this how I am implementing it.
var data;
var patientList = {};
var parseDate = d3.time.format("%d/%m/%y").parse;
function input_Data() {
d3.json("data.php", function(error, json) {
if (error) return console.warn(error);
data = json;
console.log(data);
for(var i = 0; i < data.length; i++) {
var name = data[i].name;
//data[i].dates = parseDate(data[i].dates);
if(!patientList[name]) {
var newPatient = {
dates: [data[i].dates],
alpha: data[i].alpha,
beta: data[i].beta
};
patientList[name] = newPatient;
} else {
patientList[name].dates.push(data[i].dates);
}
}
console.log(patientList);
console.log(Object.keys(patientList).length);
console.log(Object.keys(patientList));
});
}
function number_of_patients(callback) {
callback();
console.log(patientList);
console.log(Object.keys(patientList).length);
console.log(Object.keys(patientList));
}
number_of_patients(input_Data);
console.log inside the input_Data function displays correct results with length 4. And console.log in the number_of_patients displays correct patientList but 0 length and doesn't display name (keys) either. I have read similar posts but still can't fix the problem here.
Any help would be much appreciated.
In Javascript, generic objects do not have a length property.
Common facts about Javascript objects:
Objects contain key: value pairs where the keys are strings and values may be any type.
Objects do not have a .keys() method to get all of the keys, except...
Ecmascript 5 provides an Object.keys() which can be called explicitly as do some 3rd party libs like underscore.js
initialized using curly braces {} and key:value pairs
Before that, the usual way to count or access all of the keys unique to a specific instance of an object is with a loop like the following:
l=0;
for(var k in obj){
if (obj.hasOwnProperty(k)){
// hasOwnProperty ignores keys from the prototype chain
// do something with key k, value obj[k]
++l;
}
}
// the object has l keys specific to this instance
If you need to quickly get a length you should consider using an array object:
Array objects (x = [1,2,3,'sam',{'name':'fred', 'status': 'dead'}]) have numeric indices starting with 0 and can contain arbitrary type members.
have a length property (x.length is 5)
values are accessed by numeric indices with square brackets, i.e. x[2] is 3
initialized use square brackets [] containing a comma separated list of values
And as others said in comments, asynchronous calls generally return immediately -- and without the data or object you want in scope. To access the data you must execute code in the context where the data is defined, i.e. write code that accesses the asynchronous data/object in a callback function, not the main code.