在JavaScript中将对象存储在对象与数组中

时间:2017-05-01 17:53:44

标签: javascript arrays

这是一个普遍的问题,而不是我需要解决的问题。我只是一个初学者,试图了解正确的做事方式。

我想知道的是,我是否应该只使用对象作为原型(如果这是在这里使用的正确术语),或者是否可以使用它们来存储东西。

例如,在我正在研究的测试项目中,我想存储一些图像以供日后使用。我现在拥有的是:

var Images = {
    james: "images/james.png",
    karen: "images/karen.png",
    mike: "images/mike.png"
};

因为我知道位置,我想我也可以将它们放在一个数组中并适当地引用数组中的位置:

var images = ["images/james.png", "images/karen.png", "images/mike.png"];
images[0];

使用像这样的对象可以很好地工作,但我想知道哪种方法更合适。这是情境化的吗?是否有任何性能原因可以做到另一个?有一种更为公认的方式,作为一名新程序员,我应该习惯吗?

提前感谢任何建议。

3 个答案:

答案 0 :(得分:3)

实际上,你声明事物的方式会带来“关联数组和数组之间的差异”。

JS中的关联数组与对象非常相似(因为它是一个): 当您撰写var a = {x:0, y:1, z:3}时,您可以使用x(对象)或a.x(关联数组)访问a["x"]

另一方面,常规数组可以被视为关联数组,它使用无符号整数作为索引的ID。
因此,要回答您的问题,我们应该选择哪一个?

这取决于:每当我需要在名称/标签上添加对象时,我会使用对象(例如,通常不用于变量集合)。如果你要存储的东西的类型是同质的,你可能会使用一个数组(但如果你真的想要,你仍然可以找到一个对象),如果你的一些/所有东西的类型都不同于你应该去的类型一个对象(但理论上你仍然可以去一个数组)。
我们来看看:

var a = {
  x:0,
  y:0,
  z:0
}

xyz都有不同的含义(一个点的组成部分),因此一个对象在实现一个点时更好(就语义而言)。 因为var a = [0,0,0]没有比一个对象更有意义,所以我们不会在这种情况下使用数组。


var storage = {
  one:"someurl",
  two:"someurl2",
  three:"someurl3",
}

是正确的,但我们不需要每个项目的明确名称,因此我们可能会选择var storage = ["someurl","someurl2","someurl3"]




最后但并非最不重要的是,“困难”的选择:

var images = {
  cathy: "img/cathy",
  bob: "img/bob",
  randompelo: "img/randompelo"
}

var images = ["img/cathy","img/bob","img/randompelo"] 是正确的,但选择很难。因此,要问的问题是:“我们需要一个有意义的ID吗?”。

假设我们使用数据库,一个有意义的id会更好地避免每次你想做某事时的几十个循环,另一方面如果它只是一个没有任何重要性的列表(索引不重要,ex:create)每个元素元素的图像)也许我们可以尝试去一个数组。



当您在数组和对象之间犹豫时要问的问题是:键/ ID在含义方面是否重要? 如果他们是一个对象,如果他们不去寻找阵列。

答案 1 :(得分:2)

你纠正它是情境性的,但一般来说,通过仅允许一组有限的支持选项限制你的程序并不是一个好主意:

var Images = {
  james: "images/james.png",
  karen: "images/karen.png",
  mike: "images/mike.png"
};

当然,除非您碰巧知道这些将是唯一可能发生的情况 - 并且您主动不想支持其他情况。

假设您不想限制可能性,那么您的数组方法就可以了 - 尽管我个人可能会使用带有标识符的对象数组,因此您不必在其他位置跟踪索引。

类似的东西:

var userProfiles = [
  {"username": "james", "image": "images/james.png"},
  {"username": "karen", "image": "images/karen.png"},
  {"username": "mike", "image": "images/mike.png"}
];

答案 2 :(得分:1)

简介

与PHP不同,JavaScript没有关联数组。此语言中的两个主要数据结构是数组文字[])和对象文字{})。使用一个或另一个并不是风格问题,而是需要的问题,所以你的问题是相关的。

让我们进行客观的比较......

数组>对象

  1. 数组文字(间接是对象)具有比对象文字更多的方法。实际上,对象文字是Object的直接实例,只能访问Object.prototype方法。数组文字是Array的一个实例,不仅可以访问Array.prototype方法,还可以访问Object.prototype个方法(这就是在JavaScript中设置原型链的方式)。
  2. 
    
    let arr = ['Foo', 'Bar', 'Baz'];
    let obj = {foo: 'Foo', bar: 'Bar', baz: 'Baz'};
    
    console.log(arr.constructor.name);
    console.log(arr.__proto__.__proto__.constructor.name);
    
    console.log(obj.constructor.name);
    
    
    

    1. 在ES6中,对象文字不可迭代(根据可迭代协议)。但是数组是可迭代的。这意味着您可以使用for...of循环遍历数组文字,但如果您尝试使用对象文字(除非您定义[Symbol.iterator]属性),它将无法工作。
    2. 
      
      let arr = ['Foo', 'Bar', 'Baz'];
      let obj = {foo: 'Foo', bar: 'Bar', baz: 'Baz'};
      
      // OK
      for (const item of arr) {
        console.log(item);
      }
      
      // TypeError
      for (const item of obj) {
        console.log(item);
      }
      
      
      

      如果要使对象文字可迭代,则应自行定义迭代器。您可以使用生成器来执行此操作。

      
      
      let obj = {foo: 'Foo', bar: 'Bar', baz: 'Baz'};
      
      obj[Symbol.iterator] = function* () {
        yield obj.foo;
        yield obj.bar;
        yield obj.baz;
      };
      
      // OK
      for (const item of obj) {
        console.log(item);
      }
      
      
      

      数组<对象

      1. 如果由于某种原因需要描述性键,则对象文字比数组更好。在数组中,键只是数字,当您想要创建显式数据模型时,这并不理想。
      2. 
        
        // This is meaningful
        let me = {
          firstname: 'Baptiste',
          lastname: 'Vannesson',
          nickname: 'Bada',
          username: 'Badacadabra'
        };
        
        console.log('First name:', me.firstname);
        console.log('Last name:', me.lastname);
        
        // This is ambiguous
        /*
           let me = ['Baptiste', 'Vannesson', 'Bada', 'Badacadabra'];
           
           console.log('First name:', me[0]);
           console.log('Last name:', me[1]);
        */
        
        
        

        1. 对象文字是极其多价的,而数组则不是。对象文字可以创建"惯用语"类,名称空间,模块等......
        2. 
          
          let obj = {
            attribute: 'Foo',
            method() {
              return 'Bar';
            },
            [1 + 2]: 'Baz'
          };
          
          console.log(obj.attribute, obj.method(), obj[3]);
          
          
          

          Array = Object

          1. 数组文字和对象文字不是敌人。事实上,如果你一起使用它们,它们就是好朋友。 JSON 格式充分利用了这种强大的友谊:
          2. 
            
            let people = [
              {
                "firstname": "Foo",
                "lastname": "Bar",
                "nicknames": ["foobar", "barfoo"] 
              },
              {
                "firstName": "Baz",
                "lastname": "Quux",
                "nicknames": ["bazquux", "quuxbaz"]
              }
            ];
            
            console.log(people[0].firstname);
            console.log(people[0].lastname);
            console.log(people[1].nicknames[0]);
            
            
            

            1. 在JavaScript中,有一种称为类似于数组的对象的混合数据结构被广泛使用,即使您不一定意识到这一点。例如,函数中的旧的arguments对象是类似于数组的对象。像getElementsByClassName()这样的DOM方法也会返回类似数组的对象。如您所想,类似数组的对象基本上是一个特殊的对象文字,其行为类似于数组文字:
            2. 
              
              let arrayLikeObject = {
                0: 'Foo',
                1: 'Bar',
                2: 'Baz',
                length: 3 
              };
              
              // At this level we see no difference...
              for (let i = 0; i < arrayLikeObject.length; i++) {
                console.log(arrayLikeObject[i]);
              }
              &#13;
              &#13;
              &#13;

              结论

              数组文字和对象文字有各自的优点和缺点,但是根据这里提供的所有信息,我认为你现在可以做出正确的决定。

              最后,我建议您尝试ES6引入的新数据结构:MapSetWeakMapWeakSet。它们提供了许多很酷的功能,但在这里详细介绍它们会让我们走得太远......