为什么相同的值被写入数组5次?

时间:2016-12-09 08:42:12

标签: javascript arrays

echo $this->escape($this->cust['id']);
echo $this->escape($this->cust['firstname']);
echo $this->escape($this->cust['lastname']);
echo $this->escape($this->cust['postCode']);

我现在已经在这个学校任务中​​挣扎了太多时间。为什么最后一个flag.init值被写入数组5次?

2 个答案:

答案 0 :(得分:5)

它没有,但似乎就像它一样。

您正在country五次更新flag以及每次创建一个继承自{{1}的新对象时,发生了什么?并在数组上推送它。因此最终结果是数组中的五个不同对象,所有对象都继承自flag,并且没有一个具有自己的flag值。因此,您在其上看到的country是继承自country的{​​{1}},这是您分配给flag的最后一个值。

如果您希望它们从this.country继承,但每个都有拥有的 flag值,则需要记住使用country创建的对象并设置{ {1}} it

Object.create

(我在下面的图表之后展示了一种更先进的方式。)

附注:country中有一个单独的问题,这一行:

init: function(country) {
  if (country) {
    var newFlag = Object.create(flag);
    flagArray.push(newFlag);
    newFlag.country = country;
  }
},

应该只是

draw

因为数组包含对象,而不是国家字符串。也就是说,您根本不需要在var pos = flagArray.indexOf(this.country); 中使用var pos = flagArray.indexOf(this);

让我们在您当前的代码中抛出一些ASCII-Art(实际上是Unicode-art),以了解您所看到的内容:

你从内存开始:

                                                         +−−−−−−−−−−−−−−−−−−−−−−−+
flag−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−>|       (object)        |
                                                         +−−−−−−−−−−−−−−−−−−−−−−−+
                                                         | init: (function)      |
                                                         | draw: (function)      |
                                                         +−−−−−−−−−−−−−−−−−−−−−−−+

             +−−−−−−−−−−−+
flagArray−−−>|  (array)  |
             +−−−−−−−−−−−+
             | length: 0 |
             +−−−−−−−−−−−+

然后在第一次flagArray来电之后,你有:

                                                         +−−−−−−−−−−−−−−−−−−−−−−−+
flag−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−−−−−−>|       (object)        |
                                                 |       +−−−−−−−−−−−−−−−−−−−−−−−+
                                                 |       | init: (function)      |
                                                 |       | draw: (function)      |
                                                 |       | country: "ivorycoast" |
                                                 |       +−−−−−−−−−−−−−−−−−−−−−−−+
                                                 |
             +−−−−−−−−−−−+                       |
flagArray−−−>|  (array)  |                       |
             +−−−−−−−−−−−+                       |
             | length: 1 |    +−−−−−−−−−−−−−−−+  |
             | 0         |−−−>|    (object)   |  |
             +−−−−−−−−−−−+    +−−−−−−−−−−−−−−−+  |
                              | [[Prototype]] |−−+
                              +−−−−−−−−−−−−−−−+

您已创建了一个以draw为原型的新对象,并将init flag设置为flag

第二次致电country后,您有:

                                                         +−−−−−−−−−−−−−−−−−−−−−−−+
flag−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−+−−−−>|       (object)        |
                                                 | |     +−−−−−−−−−−−−−−−−−−−−−−−+
                                                 | |     | init: (function)      |
                                                 | |     | draw: (function)      |
                                                 | |     | country: "sweden"     |
                                                 | |     +−−−−−−−−−−−−−−−−−−−−−−−+
                                                 | |
             +−−−−−−−−−−−+                       | |
flagArray−−−>|  (array)  |                       | |
             +−−−−−−−−−−−+                       | |
             | length: 2 |    +−−−−−−−−−−−−−−−+  | |
             | 0         |−−−>|    (object)   |  | |
             | 1         |−+  +−−−−−−−−−−−−−−−+  | |
             +−−−−−−−−−−−+ |  | [[Prototype]] |−−+ |
                           |  +−−−−−−−−−−−−−−−+    |
                           |                       |
                           |   +−−−−−−−−−−−−−−−+   |
                           +−−>|    (object)   |   |
                               +−−−−−−−−−−−−−−−+   |
                               | [[Prototype]] |−−−+
                               +−−−−−−−−−−−−−−−+

...依此类推,直到"ivorycoast"填充了五个单独的对象,所有对象都使用init作为原型,flagArray flag为其flag 1}}属性。

以下是我提到的添加"norway"的更高级方法。如果我正在编写生产代码,我不会将其用于此(太冗长),但仅仅是为了完整性:还有第二个参数,你可以给country一个可以有一个属性列表的添加到新对象。您可以通过提供属性来指定属性,并通过对象指定属性的各个方面,例如它是否可枚举,是否为只读或可写,其初始值值(或getter和/或setter)等。当您执行此操作时,属性的countryObject.createwritable功能都默认为enumerable,但当您通过分配属性创建属性时,它们默认为configurable。因此,要对false执行同样的操作,我们必须指定所有这些内容并说出true以使属性相同。

所以,这与先前使用newFlag.country = country的版本完全相同,只是没有临时变量:

true

答案 1 :(得分:1)

使用Object.create(flag)flag设置为数组中每个元素的原型。原型在所有对象之间共享,因此this.country在每个init调用中的原型对象上更新,并由数组中的每个元素继承。

要创建单独的对象,您应该尝试Object.assign,例如:

flagArray.push(Object.assign(Object.create(flag), { country : country }));

https://jsfiddle.net/p58189f1/