I got json data from the server by ajax:
request.responseText=[{name:xxx},{name:xxx},{name:xx}].
Then I use the
var data=eval(request.responseText);
alert(data.length);
In IE,it is "4",while in Firefox it is "3".
Use the IE debugger I found that the element in data is like:
[Methods]
[0]
[1]
[2]
So itis length is 4.
I wonder why?
My guess is that the server returned data with a trailing comma, for example:
[1, 2, 3, ]
In IE, this array will be interpreted as having a length 4, while in standard compliant browsers, it will have a length 3.
[Methods] is a separate node shown by the debugger to separate functions from other values.
It does not actually exist in the object.
If an array has three items named 0, 1, and 2, its length will be 3.
Related
consider this code
example 1:
function plus(a) {return a+10}
([1]) // "110"
example 2:
var arr = [1,2,3,4,5,6,7]
arr[[1]] // 2
arr.splice([1],1);
arr // (6) [1, 3, 4, 5, 6, 7]
can someone explain why passing in an array as an argument, gets converted to a string? (that's what it looks like happened here)
can someone explain why passing in an array as an argument
It doesn't.
It gets treated as an array right up until the point where you try to use the addition operator on it.
It hits the step Let rprim be ? ToPrimitive(rval) and converts it according to those rules.
And so on until it calls the array's toString method.
Similar rules apply in the other examples.
In short: When it makes no sense at all to use an array in a given context, type conversion is applied to turn it into a data type that is apropriate.
Javascript automatically outputs a certain data type when two different data types are added.
Here are two examples:
2 + 3 // 5
2 + "hello" // "2hello"
When two numbers are added, an integer is output. However, 2 and hello can't be added numerically, so everything is first automatically converted to a string, and then appended.
The same thing happens in your case – a remains an array, but an array can't be added to a number. So both are converted to strings and then appended, and the end result is a string.
You were probablly thinking of adding a value to the end of an array. This is done using:
a.push(10);
Or, if you wanted to add the first item in the array and 10 to get the result 11, use:
return a[0] + 10
But you can't add a single number to a whole array, only to one of the items or at the end of the array.
Answer #1 - you get a string from the array.toString so you need to cast back to number - here I use +
function plus(a) {return +a+10}
console.log(plus([1]))
Second
var arr = [1,2,3,4,5,6,7]
console.log(arr[1]) // 2
console.log(arr[[1]]) // 2
arr.splice([1],1); // removes the second item
console.log(arr)
var arr = [1,2,3,4,5,6,7]
arr.splice(1,1); // just as if you had done this
console.log(arr) // [1, 3, 4, 5, 6, 7]
The + operator doesn't work for arrays. It only works for numbers or strings.
Since javascript can't use your array with the + operator, it converts it to string before. That's why plus([1]) is "110"
You can use the push method if you want to add to an array:
array.push(newElement);
In the second example, inside splice, your array is used with an operator that doesn't support it so it is converted to a number. If you look at the MDN definition of splice, you see it expects a number, not an array.
When you want to use splice, you don't pass an array as the first argument, you pass the index of the first element to remove. If you want to remove 2 from your array, you do arr.splice(1,1);
I'm doing some small experiments based on this blog entry.
I am doing this research in Google Chrome's debugger and here comes the hard part.
I get the fact that I can't delete local variables (since they are not object attributes). I get that I can 'read out' all of the parameters passed to a function from the array called 'arguments'. I even get it that I can't delete and array's element, only achieve to have array[0] have a value of undefined.
Can somebody explain to me what undefined x 1 means on the embedded image?
And when I overwrite the function foo to return the arguments[0], then I get the usual and 'normal' undefined.
This is only an experiment, but seems interresting, does anybody know what undefined x 1 refers to?
That seems to be Chrome's new way of displaying uninitialized indexes in arrays (and array-like objects):
> Array(100)
[undefined × 100]
Which is certainly better than printing [undefined, undefined, undefined,...] or however it was before.
Although, if there is only one undefined value, they could drop the x 1.
Newer versions of Chrome use empty instead of undefined to make the difference a bit clearer.
For example, entering [,,undefined,,] in the DevTools console results in:
▼(4) [empty × 2, undefined, empty]
2: undefined
length: 4
▶__proto__: Array(0)
Google Chrome seems to choose to display sparse array using this undefined x n notation. It will show [undefined, undefined] if it is not a sparse array:
var arr = new Array(2);
console.log(arr);
var arr2 = [];
arr2[3] = 123;
console.log(arr2);
var arr3 = [,,,];
console.log(arr3)
var arr4 = [,];
console.log(arr4)
var arr5 = [undefined, undefined]
console.log(arr5)
var arr6 = [undefined]
console.log(arr6)
arr1 to arr4 are all sparse arrays, while arr5 and arr6 are not. Chrome will show them as:
[undefined × 2]
[undefined × 3, 123]
[undefined × 3]
[undefined × 1]
[undefined, undefined]
[undefined]
note the [undefined x 1] for the sparse array.
Since you deleted an element, it follows that: If you delete an element from an array, the array becomes sparse.
Here is how it looks, Type this code into chrome devtools console:-
arr = new Array(4);
arr[2] = "adf";
console.log(arr); // [undefined × 2, "adf", undefined × 1]
See the first two consecutive "undefined" that are represented by *2, to show that there are two consecutive undefined there
It just happened to me too. Open the same thing in another browser and output/log the array to the console. As long as it works in both crome and in firefox the same way (as in accessing the elements works fine even if the output has the undefinedx1), I consider it some kind of bug in Chrome not refreshing something internally. You can actually test it this way:
I was adding elements to an array, and firing console.log() to log the element, to check if it was undefined or not. They were all defined.
After push() I logged the array and it seemed that when this happened, it was always the last one being undefined x 1 on Chrome.
Then I tried logging it more times and also later, but with the same result.
However when I accessed (for the sake of output), the element by its index, it returned the proper value (funny).
After that I logged the array again and it said the last index was undefined x 1 (the very one I just accessed directly with success!).
Then I did a for loop on the array, logging or using each element, all showed up fine.
Then another log on the array, still buggy.
The code I'm originally using has checks for undefined and they didn't fire, but I was seeing all these undefineds in the console and it was bugging me (no pun intended).
Also worth reading: Unitialized variables in an array when using only Array.push? I'm using pop() too in my code and it's a reasonable explanation that the console log actually represents a different state in time (when the code is 'halted').
I've been surprised to find that:
var a = [1, 2, 3];
a[-1] = 4;
can have different results:
in chrome -> a is then [1, 2, 3]
in node -> a is then [1, 2, 3, '-1': 4]
what is the expected behavior, if any?
The result should be the same no matter what. Either one may display differently in the console, but in practice, the fashion in which values are displayed in the console shouldn't really have any bearings on the underlying mechanics. In this case, the effect is the same: the property named -1 is set to 4. However, you won't be able to iterate through this normally, unless you specifically set your start value to -1, and the value at -1 very probably (don't quote me on this) won't be reflected in the array's length property.
If you're interested, the ECMAScript specification for Arrays is here:
http://ecma-international.org/ecma-262/7.0/index.html#sec-array-objects
and the length property of Array instances is defined here:
http://ecma-international.org/ecma-262/7.0/index.html#sec-properties-of-array-instances-length
Today when I read undersocre, I found an interesting syntax ["length"]
For example:
"hello"["length"] //5
[1,2,3,4]["length"] //4
This works in Chrome, Firefox and even IE5!
Is this a native js method or does it run in a array way like [1,2,3]["1"] or something like that?
It's a standard property of Array: Array#length
The length property represents an unsigned, 32-bit integer that is always numerically greater than the highest index in the array.
Or a standard property of String: String#length
The length property represents the length of a string.
It is a different use of a property accessor.
[0, 1, 2].length
[0, 1, 2]['length']
I have noticed something that I cannot understand at all. I am doing something really simple in JavaScript:
var a = [1,2,3];
console.log(a.push(4));
console.log(a);
console.log(a.push(5));
I would expect the console to log: 4, [1,2,3,4], and 5 as described here for example.
The catch is that the actual console output looks like: 4, [1,2,3,4,5], and 5
See: http://jsfiddle.net/HknMF/
What on earth makes the 5 appear in the second log output?
EDIT: fwiw here's a screenshot of Firebug showing both behaviors: http://i.imgur.com/fwAK3.png
The console in some browsers uses a reference to the array/object, so when you inspect it and the object changed after the console.log() call you'll see the changed object.
In Firefox this also happens for objects, but not for arrays which are displayed inline anyway:
>>> var a = [1,2,3]; console.log(a.push(4)); console.log(a); console.log(a.push(5));
4
[1, 2, 3, 4]
5
Especially for objects that do not contain functions a quick workaround is either cloning them (log $.extend({}, yourObject) if you have jQuery) or logging their JSON string version (then you lose the nice object view and just get a plain string though). An array can easily cloned (shallow copy!) using a.slice(0)
Dependent of the Browser either your live array gets logged (Chrome) or A string representation (Firefox).
A shallow copy is sufficient to prevent that. Use:
console.log( a.slice(0) );
for that.