Javascript 对js proto和分配新属性感到困惑
我有一个简单的对象(实际上是senchatouch中的一个按钮)。它位于一个名为'something.aButton()'的对象中 此对象包含一个名为“view”的属性,其值为“home” 现在我想把它分配给一个变量,分配一些新的属性并传递给它 因此,我:Javascript 对js proto和分配新属性感到困惑,javascript,sencha-touch,prototype,Javascript,Sencha Touch,Prototype,我有一个简单的对象(实际上是senchatouch中的一个按钮)。它位于一个名为'something.aButton()'的对象中 此对象包含一个名为“view”的属性,其值为“home” 现在我想把它分配给一个变量,分配一些新的属性并传递给它 因此,我: var c = something.aButton(); 现在我分配了更多的内容: c.id = 4; c.class = 'class'; c.id = 4; c.class = 'class'; 现在的问题是c.view是未定义的,
var c = something.aButton();
现在我分配了更多的内容:
c.id = 4;
c.class = 'class';
c.id = 4;
c.class = 'class';
现在的问题是c.view是未定义的,除非我:
c.view = 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';
c.id = 4;
c.class = 'class';
我会避免使用标识符类
。它在第三版JavaScript中是一个保留字,在第五版中是“松散”(非严格)代码
现在的问题是c.view是未定义的,除非我:
c.view = c.view;
c.view = c.view;
它不是未定义的。您正在更改的是c
中有自己的视图
属性副本的内容。如果您刚刚执行了console.log(c.view)
,即使不执行上面的赋值,您也会在控制台中看到它的值
原型在JavaScript中的工作方式是,对象由原型以实时的方式备份。因此,如果您从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 |
|-----------| |---------------|
| bar: "43" | | bar: "42" |
+-----------+ +---------------+
因为f
现在有自己的bar
属性,JavaScript引擎使用该属性的值。现在我们的图表如下所示:
+-----------+ +---------------+
| f |----->| Foo.prototype |
|-----------| |---------------|
| | | bar: "42" |
+-----------+ +---------------+
+-----------+ +---------------+
| f |----->| Foo.prototype |
|-----------| |---------------|
| bar: "43" | | bar: "42" |
+-----------+ +---------------+
…因此,从f
检索bar
时,会再次查看原型,因为f
没有名为bar
的属性。我们回到原始的对象图:
+-----------+ +---------------+
| f |----->| Foo.prototype |
|-----------| |---------------|
| | | bar: "42" |
+-----------+ +---------------+
因为
f
没有bar
属性,引擎会查看原型。这就是我所说的“活”系统的意思。你的断言c.view=c.view代码>影响c值的更改。视图
不正确。我不能告诉你你所看到的奇怪行为背后的原因,因为不清楚那是什么,我也不是Sencha touch专家(甚至不熟悉它)。还有其他问题。。。虽然c.view=c.view
可以将属性从c
的原型复制到c
的当前实例,但如果之前未定义,则不会定义属性,因为读取属性会遍历原型链。这开始有意义了。我假设我必须执行c.view=c.view,因为Sencha或我的一些代码必须检查该值是在当前对象中还是在其原型中设置的。因此,我所关心的问题是,如何创建一个像原型一样填充了所有值的新实例facing@Joshua:你不应该做c.view=c.view代码>,我从来没有在野外的代码中看到过它,只是为了说明问题而创建的人工场景。使用c
的代码必须特别注意检查它是否有自己的视图
属性,或者是从原型中获取的属性,这样做的理由很少。使用c
的代码应该只从中检索view
,而不关心它来自何处。@Joshua:“那么,我如何创建一个新实例,并像原型一样填充其所有值,这是我面临的问题”如果您真的需要这样做,只需使用for.
循环,因为这将循环对象的所有可枚举属性<代码>变量newc,名称;newc={};对于(c中的名称){newc[name]=c[name];}
现在newc
具有c
的所有可枚举属性(无论它们来自何处)。但同样,这样做的理由很少。谢谢-这可能是框架的一个特点-我已经用其他方式解决了它,但谢谢你的解释