9

What is going on here?

var x = {length:3, '0':'foo', '1':'bar','2':'f', splice:function(){}}

This actually creates an array:

["foo", "bar", "f"]

Where is the documentation for this structure syntax?

It's also smart:

changing to: (notice 0 , 1 , 3)

 var x = {length:3, '0':'foo', '1':'bar','3':'f', splice:function(){}}

will mess up the array and it will be:

["foo", "bar", undefined × 1]

Also, removing the splice function:

var x = {length:3, '0':'foo', '1':'bar','2':'f'}

yields: (regular object)

Object
0: "foo"
1: "bar"
2: "f"
length: 3
__proto__: Object

So I have two questions:

  • What is this structure? length , element , splice

  • Say I have ['john','paul','yoko'] and now I want to create the object

    var x = {length:3, '0':'john', '1':'paul','2':'yoko', splice:function(){}}

    How would I do this?

2
  • this actually creats an array, why? Because the console shows it as an array? Probably just some optimised test. x.constructor gives function Object() .... Commented Oct 29, 2012 at 9:50
  • Yoshi you got a point : Object.prototype.toString.apply(x) = "[object Object]" Commented Oct 29, 2012 at 9:51

4 Answers 4

6

An array is nothing else than an object, with some methods implemented, when you make console.log(x), your console recognizes the model of an array, and display it like it has been configured to do so.

Array is an object available by default in Javascript, and it is handled a bit differently than other objects by the browser (see @MathiasSchwarz comment), but in its structure, it is an object like the others (there's methods that you can call, and you can add indexes. Though, you don't usually use string indexes like in "normal" objects, because it's not aimed to be used like that).

But your object is not really an Array, you can do whatever you want without referring to what is displayed in the console.

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

5 Comments

why the splice func is there ?
That is not entirely correct. Arrays are a special kind of objects. The printing behavior is simply caused by the fact that an array has a toString method. Such a method could easily be implemented by a programmer as well. The special thing about arrays is the length field which is automatically updated when the array is updated. Such a field cannot be implemented by a programmer, so it is indeed more than an object...
@RoyiNamir: Thats because the console recognises it as an array by looking if there are length and splice fields in it (IMO).
You can have string indexes inside an Array. They just don't count towards the length.
@JanDvorak Yes, I edited my post. I think arrays have been created to be used with number indexes to be able to browse them with a integer variable, and that was what I wanted to say.
3

x is not an array, it's just an object. (The console shows it in array format, that's the problem of implementation of the console.)

var x = {length:3, '0':'foo', '1':'bar','2':'f', splice:function(){}};
console.log(typeof x); // object

Just use firebug as the example, take a look at the firebug's source code, and you will see why the console thought it as an array.

//...
isArray: function(obj, win)
{
    if (mightBeArray(obj, win))
    {
        if (!obj)
            return false;
        // do this first to avoid security 1000 errors
        else if (obj instanceof Ci.nsIDOMHistory)
            return false;
        // do this first to avoid exceptions
        else if (obj.toString && obj.toString() === "[xpconnect wrapped native prototype]")
            return false;
        else if (isFinite(obj.length) && typeof obj.splice === "function")
            return true;
        else if (Arr.isArray(obj))
            return true;
    }

    return false;
},
// ...

1 Comment

Object.prototype.toString.apply(x) "[object Object]" is better IMHO
2
var x = {length:3, '0':'foo', '1':'bar','2':'f', splice:function(){}}

looks like an array but isn't. If you try x.forEach(function(e){...}) it fails but if you do [1,2,3].forEach(function(e){...}).

If you want to create an actual array through the literal object notation, you could do

var x = {length:3, ... , __proto__:Array.prototype}

Note, however, an object created like this still won't update it's length property on write.

Objects that have a length and numeric indexes are called pseudo-arrays is Javascript. An example of these is the jQuery object.

The Chrome console displays objects with a length and splice as arrays but that doesn't mean they are arrays.

Comments

0

The created object is not an array, but it will behave as one (immutable though) because it has a length field and a splice method.

In a JavaScript Array the length field is automatically updated when the array is updated. This will not be the case for your object. In your object, the length field will remain 3 no matter what the object contains. This is also the reason why things no longer work when you change the indices to 0,1,3. In this case the length field should have been 4 rather than 3. Since the value is 3 the iteration will stop after index 2 which is indeed undefined since you didn't set a value for index 2...

2 Comments

What makes you believe the resulting array is immutable?
Well, it isn't immutable as an object as such, but the splice function won't do anything and none of the mutation functions for Array are available. That's what I mean...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.