Actually, I am working on someone others code.
While resolving a bug I found
such types of things.
Note: API is giving productNumber in number type.
Sometimes passing only one productNumber in new Array(). then a new
bug occurs.
And when entering productNumber more than one then working fine.
Why arr1[0] is giving undefined.
var productNumber1 = 1001;
var arr1 = new Array(productNumber1);
console.log("arr1",arr1[0]);
var productNumber2 = '1001';
var arr2 = new Array(productNumber2);
console.log("arr2",arr2[0]);
Could you please someone explain this behavior.
In case1 the argument you passing getting treated as a length of the array
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
A JavaScript array is initialized with the given elements, except in the case where a single argument is passed to the Array constructor and that argument is a number (see the arrayLength parameter below). Note that this special case only applies to JavaScript arrays created with the Array constructor, not array literals created with the bracket syntax.
arrayLength
If the only argument passed to the Array constructor is an integer between 0 and 2^32-1 (inclusive), this returns a new JavaScript array with its length property set to that number (Note: this implies an array of arrayLength empty slots, not slots with actual undefined values). If the argument is any other number, a RangeError exception is thrown.
So actually in case1, you are creating an array with length 1001.
However in case 2, that is getting treated as an element since it's not a number.
This is described in the documentation for the Array constructor:
If the only argument passed to the Array constructor is an integer between 0 and 232-1 (inclusive), this returns a new JavaScript array with its length property set to that number
So if you pass a number like 1001 you'll set the length, but if you pass a string like '1001', you'll set the first value, and if you pass multiple arguments you will set multiple values.
Just don't use the Array constructor. Use the square bracket literal notation instead. That avoids the problem.
var productNumber1 = 1001;
var arr1 = [productNumber1];
console.log("arr1",arr1[0]);
var productNumber2 = '1001';
var arr2 = [productNumber2];
console.log("arr2",arr2[0]);
You may also use the Array.of() tool for this job.
var p1 = 1001,
p2 = "1001",
a1 = Array.of(p1),
a2 = Array.of(p2);
console.log(a1);
console.log(a2);
Related
Where foo is a defined variable, why is it that the following code:
var array = [].push(foo);
when outputted, equals 1?
From my tests, outputting array will simply output the length of the array.
So the code:
var array = [10,20].push(foo);
would give a value of 3.
As a related question (and to clarify what my code intended to do), why does this not intuitively do what it appears to do, ie:
var array = [];
array.push(foo);
where outputting array gives the expected result of [foo]?
When you use push method it returns length of array. So when you do:
var array = [10,20].push(foo);
you get [10, 20, foo] length of this array is three. But as you say var array it stores returned length from push method in this variable.
Array.prototype.push() always returns the new number of elements in the array. It does not return this instance or a new Array instance. push() is a mutator actually changes the contents of the array.
instead you can try
var array, foo = 30;
(array = [10,20]).push(foo);
console.log(array)
push is a function and it returns an integer representing the length of the array.
Imagine the definition of this function as
int push(object obj);
When you do this:
var array = [].push(foo);
You are actually running the function and returning the value.
Because the return value of push is the new length of the array Documentation and examples.
In your second example, you cited outputting the array, which is going to give you the new array in both cases. However, the returned result of your second case is the new array length as well
var array = [];
array.push(foo); //If you do this in the console, you'll see that 1 gets returned.
console.log(array); //While this will print out the actual contents of array, ie. foo
The definition of push() method including two parts in javascript: Part 1: it adds one or more elements to the end of an array, part 2: it returns the new length of the array.
I think you are missing the part 2 in your understanding of this method.
jQuery inArray returns -1 if the array contains single element.
var a = Array(1);
console.log($.inArray(1,a));
This returns -1. But if the array contains 2 or more elements it works perfectly.
var a = Array(1,2,3);
console.log($.inArray(1,a));
Returns perfect position.
Contrary to what you seem to think, Array(1) doesn't create an array with element 1 but an array of size 1. That's a specific behavior you get when you pass only one argument and it's an integer.
From the MDN :
If the only argument passed to the Array constructor is an integer
between 0 and 2^32-1 (inclusive), this returns a new JavaScript array
with length set to that number.
You should probably almost never use this Array constructor whose strange behavior leads to many bugs and which is mostly useless. Use this :
var a = [1];
var x = new Array(10);
$.inArray(10,x);
#Returns -1
Fiddle
I've come across this weird issue, checking a value in an array with $.inArray, really simple.
But, if the array only has one value in it, inArray returns -1.
If I add another value to the array, it works as expected.
This only happens with integers and not with strings.
What's going on?!
If you want to create an array with the one number(10) inside you should use bracket literal:
var x = [10];
$.inArray(10,x);
Or with push:
var x = new Array();
x.push(10);
Obviously the first one is more readable and faster to write.
A JavaScript array is initialized with the given elements, except in the case where a single argument is passed to the Array constructor and that argument is a number. Note that this special case only applies to JavaScript arrays created with the Array constructor, not with array literals created with the bracket syntax.
If the only argument passed to the Array constructor is an integer, a new, empty JavaScript array and its length is set to that number
MDN
Fixed fiddle
I suggest to check documentation for arrays in JavaScript, link: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array
In your case, by using:
var x = new Array(10);
It creates an array with length 10 and each item of the array is undefined
I suggest to use:
var x = [10];
this is an array with one item at index 0 that has value 10.
var x = new Array(10); creates an array with 10 slots, not an array that contains "10"
I see four five options to initialize an array to a specific length in JS, (the last one is a stretch, I know):
var a = []; a.length = 5;
var a = Array(5);
var a = []; a[4] = undefined;
var a = new Array(5);
function makeArrayToLength(length, default){
var a = [], i = 0;
for(; i < length; i++){
a[i] = default;
}
return a;
}
I definitely want to (and do) use the literal whenever possible, but I'm in a situation where the defining aspect of a particular array is its length, so I'm leaning towards Array(5). Is the first example equivalent to the second in terms of end result? I realize it's not equivalent in the execution.
The first two, and the third examples are equivalent, at the end they produce an Array object with only one own property, length, containing 5 as its value.
When you call the Array constructor using a single numeric argument (like Array(5);), the newly created object will contain that number as its length property, the index properties aren't created:
var a = Array(5);
a.hasOwnProperty('0'); // false
The second example produces just the same:
var a = [];
a.length = 5;
a.hasOwnProperty('0'); // false
About the third example, it isn't equivalent because it will create a property on the array object, even though its value is undefined:
var a = []; a[4] = undefined;
a.hasOwnProperty('4'); // true
The fourth example:
var a = new Array(5);
Is just exactly the same as the second one (var a = Array(5);), there's no difference between using the Array constructor with or without the new operator, in the second example you are calling the Array constructor as a function.
And finally, about your makeArrayToLength function, by now I think you know isn't equivalent at all, since all the "index properties" are initialized to a "default" value. (BTW don't use default as Identifier, it's a Keyword...)
The Array constructor is usually avoided because it can have different behaviors depending the argument used, for example:
Array("5"); // one element array, (["5"])
Array(5); // empty array, length = 5
// v.s.
["5"] // one element array
[5] // one element array
Also, the Array constructor could be overriden, while array literals will always work.
Yes, they all produce the same result.
2 and 4 are the same because, according to the ECMAScript spec:
15.4.1 The Array Constructor Called as a Function When Array is called as a
function rather than as a constructor,
it creates and initialises a new Array
object. Thus the function call
Array(...) is equivalent to the object
creation expression new Array(...)
with the same arguments.
1 and 2 are equivalent because [] constructs a new array and setting the length property is equivalent to constructing an Array with new Array(length) (in the spec).
Option 3 is also equivalent because:
...whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index
And option 5 is basically just option 3, but repeated multiple times up to the maximum index.
Could someone explain this (strange) behavior? Why is the length in the first example 3 and not 2, and most importantly, why is the length in the second example 0? As long as the keys are numerical, length works. When they are not, length is 0. How can I get the correct length from the second example? Thank you.
a = [];
a["1"] = {"string1":"string","string2":"string"};
a["2"] = {"string1":"string","string2":"string"};
alert(a.length); // returns 3
b = [];
b["key1"] = {"string1":"string","string2":"string"};
b["key2"] = {"string1":"string","string2":"string"};
alert(b.length); // returns 0
One thing to note is that there is a difference between regular arrays and associative arrays. In regular arrays (real arrays), the index has to be an integer. On the other hand, associative arrays can use strings as an index. You can think of associative arrays as a map if you like. Now, also note, true arrays always start from zero. Thus in your example, you created an array in the following manner:
a = [];
a["1"] = {"string1":"string","string2":"string"};
a["2"] = {"string1":"string","string2":"string"}
Javascript was able to convert your string indexes into numbers, hence, your code above becomes:
a = [];
a[1] = {"blah"};
a[2] = {"blah"};
But remember what i said earlier: True arrays start from zero. Therefore, the javascript interpreter automatically assigned a[0] to the undefined. Try it out in either firebug or the chrome/safari console, and you will see something like this when you try to print "a". You should get something like "[undefined, Object, Object]. Hence the size 3 not 2 as you expected.
In your second example, i am pretty sure you are trying to simulate the use of an associated array, which essentially is adding properties to an object. Remember associated arrays enable you to use strings as a key. So in other terms, you are adding a property to the object. So in your example:
b["key1"] = {"string1":"string","string2":"string"};
this really means:
b.key1 = {"string1":"string","string2":"string"};
Initializing b =[] simply creates an array, but your assignment doesn't populate the array. It simply gives "b" extra properties.
length returns 1 + the largest integer key in the object.
In a the largest key is 2 so 1+2 is 3.
In b there are no integer keys (the keys there are key1 and key2 which cannot be converted into ints) so Javascript assumes that the largest key is -1, and 1 + -1 yields 0.
This program will help you see that:
a = [];
a["1"] = {};
a["4"] = {};
alert(a.length); // Prints 5
From the ECMAScript standard, ECMA-262, 5th ed.
15.4.5.2 length
The length property of this Array object is a data property whose value is always numerically greater than the name of every deletable property whose name is an array index.
Note the length property of an array only takes into account array indices, which are integers; setting other properties doesn't affect length.
For an array, a["3"] is equivalent to a[3] (this behavior is specified by ยง 15.4.5.1); 3 is an array index rather than a property. Thus setting a["3"] affects the array's length. b["key1"] is equivalent to b.key1. Setting properties don't affect the length of a collection.