简体   繁体   English

在JavaScript中用Object创建数组(反之亦然)?

[英]Creating array by Object (and vice versa) in JavaScript?

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) 改为:(注意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 假设我有['john','paul','yoko'] ,现在我想创建对象

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

    How would I do this? 我该怎么做?

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. 一个数组只是一个对象 ,实现了一些方法,当你创建console.log(x) ,你的控制台会识别一个数组的模型,并像配置它一样显示它。

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). Array是默认情况下在Javascript中可用的对象,它的处理方式与浏览器的其他对象略有不同(请参阅@MathiasSchwarz注释),但在其结构中,它是一个像其他对象一样的对象(可以调用的方法,并且你可以添加索引。但是,你通常不会像在“普通”对象中那样使用字符串索引,因为它的目的不是像那样使用它。

But your object is not really an Array , you can do whatever you want without referring to what is displayed in the console. 但是你的对象实际上并不是一个Array ,你可以做任何你想做的事情,而无需参考控制台中显示的内容。

x is not an array, it's just an object. x不是数组,它只是一个对象。 ( 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. 只需使用firebug作为示例,查看firebug的源代码,您将看到为什么控制台将其视为一个数组。

//...
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;
},
// ...
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){...}) . 如果你尝试x.forEach(function(e){...})它会失败,但如果你做[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. 但是请注意,像这样创建的对象仍然不会在写入时更新它的length属性。

Objects that have a length and numeric indexes are called pseudo-arrays is Javascript. 具有长度和数字索引的对象称为伪数组是Javascript。 An example of these is the jQuery object. 这些的一个例子是jQuery对象。

The Chrome console displays objects with a length and splice as arrays but that doesn't mean they are arrays. Chrome控制台 显示 lengthsplice为数组的对象,但这并不意味着它们数组。

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. 创建的对象不是数组,但它将表现为一个(虽然不可变),因为它有一个长度字段和一个splice方法。

In a JavaScript Array the length field is automatically updated when the array is updated. 在JavaScript数组中,更新数组时会自动更新length字段。 This will not be the case for your object. 对于您的对象,情况并非如此。 In your object, the length field will remain 3 no matter what the object contains. 在您的对象中,无论对象包含什么, length字段都将保持为3 This is also the reason why things no longer work when you change the indices to 0,1,3. 这也是将索引更改为0,1,3时不再起作用的原因。 In this case the length field should have been 4 rather than 3 . 在这种情况下,长度字段应该是4而不是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... 由于值为3 ,迭代将在索引2之后停止,这确实是未定义的,因为您没有为索引2设置值...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM