对jsproto和分配新属性感到困惑

Confused about js proto and assigning new properties

本文关键字:属性 jsproto 分配 新属性      更新时间:2023-09-26

我有一个简单的对象(实际上是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'
  ....

现在我分配更多的东西:

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

我会避免使用标识符class。这是JavaScript第三版中的保留字;松散的";第5版中的(非严格)代码。

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

c.view = c.view;

它不是未定义的。您要更改的是c拥有view属性的自己的副本。如果你只做了console.log(c.view),你会在控制台中看到它的值,即使没有做上面的赋值。

原型在JavaScript中的工作方式是由原型以live的方式备份对象。因此,如果从c中获取view的值,并且c没有其自己的属性view,则会检查其原型链。但是,如果c上为view分配一个值,则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"

因此,从f检索bar再次看起来像原型,因为f没有名为bar的属性。我们回到了原始的对象图:

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

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

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

因为f没有bar属性,所以引擎会查看原型。这就是我所说的一个实时系统。