对js proto感到困惑并分配新属性

时间:2012-02-05 16:53:21

标签: javascript sencha-touch prototype

我有一个简单的对象(实际上是Sencha Touch中的一个按钮)。它位于一个名为'something.aButton()'的对象中;

此对象包含名为“view”的属性,其值为“home”;

现在我想将它分配给一个变量,分配一些新的属性并传递它。

所以我这样做:

var c = something.aButton();

现在我分配一些东西:

c.id = 4;
c.class = 'class';

现在的问题是c.view未定义,除非我这样做:

c.view = c.view;

哪一个 - 来自PHP世界让我感到困惑。我得到了原型的基础知识,但不明白我如何简单地将我的对象分配给变量以便于使用和工作。我不知道所有的原始属性,所以重新分配它是不可能在我的代码中我不知何故怀疑这是正确的方式。

如果我将“c”转储到我的控制台,我会看到:

Ext.Object.classify.objectClass
class: "class"
id: 4
__proto__: Object
  view: 'home'
  ....

1 个答案:

答案 0 :(得分:3)

  

现在我分配一些东西:

c.id = 4;
c.class = 'class';

我会避免使用标识符class。这是第3版JavaScript中的保留字,以及第5版中的“松散”(非严格)代码。

  

现在的问题是c.view未定义,除非我这样做:

c.view = c.view;

这不是未定义的。您正在更改的内容是c拥有}属性的自己的副本。如果您刚刚执行view,即使没有执行上述分配,您也会在控制台中看到它的值。

原型在JavaScript中的工作方式是该对象由 live 方式的原型备份。因此,如果您从console.log(c.view)获取view的值,并且c没有名为c拥有的属性,则其原型链为检查。但是,如果您<{>> view view上的c,那么c将获得具有该名称的拥有的属性,并且你在对象转储等中看到它。

所以这是一个简化的例子:

function Foo() {
}
Foo.prototype.bar = "42";

var f = new Foo();
console.log(f.bar); // "42"

目前,我们的对象图如下所示:

+-----------+      +---------------+
|     f     |----->| Foo.prototype |
|-----------|      |---------------|
|           |      | bar: "42"     |
+-----------+      +---------------+

所以我们有f,它由原型Foo.prototype支持。当我们向f询问属性bar时,由于f没有该名称的属性,因此JavaScript引擎会查看其原型以查看是否的确如此。如果是,则使用该值。 (如果原型有原型等,这种情况会持续下去)

现在假设我们这样做:

f.bar = "43";
console.log(f.bar); // "43"

由于f现在拥有拥有的 bar属性,因此JavaScript引擎会使用该属性的值。现在我们的图表看起来像这样:

+-----------+      +---------------+
|     f     |----->| Foo.prototype |
|-----------|      |---------------|
| bar: "43" |      | bar: "42"     |
+-----------+      +---------------+

我们可以删除 f的属性:

delete f.bar;       // `delete` removes "own" properties from objects
console.log(f.bar); // "42"

...所以从bar检索f再次查看原型,因为f没有名为bar的属性。我们回到原始对象图:

+-----------+      +---------------+
|     f     |----->| Foo.prototype |
|-----------|      |---------------|
|           |      | bar: "42"     |
+-----------+      +---------------+

现在有趣的一点:假设我们改变原型的属性?

Foo.prototype.bar = "baz";
console.log(f.bar); // "baz"

由于f没有bar属性,引擎会查看原型。这就是我所说的 live 系统。