Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/428.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
意外设置Javascript对象实例属性_Javascript_Prototypal Inheritance_Function Constructor - Fatal编程技术网

意外设置Javascript对象实例属性

意外设置Javascript对象实例属性,javascript,prototypal-inheritance,function-constructor,Javascript,Prototypal Inheritance,Function Constructor,我有以下代码: function Foo() { Foo.prototype.test = 0; } Foo.prototype.incTest = function() { Foo.prototype.test++; }; Foo.prototype.getTest = function(name) { console.log(name +" this: " + this.test + " proto: " + Foo.prototype.test); }; va

我有以下代码:

function Foo() {
    Foo.prototype.test = 0;
}

Foo.prototype.incTest = function() {
    Foo.prototype.test++;
};

Foo.prototype.getTest = function(name) {
    console.log(name +" this: " + this.test + " proto: " + Foo.prototype.test);
};

var bar = new Foo();
var baz = new Foo();

bar.getTest('bar');
bar.incTest();
bar.getTest('bar');

baz.incTest();
bar.getTest('bar');
baz.getTest('baz');
可预测的结果是:

bar this: 0 proto: 0
bar this: 1 proto: 1 
bar this: 2 proto: 2 
baz this: 2 proto: 2 
现在,我尝试利用
这个
查找原型链,并将
incTest
更改为:

Foo.prototype.incTest = function() {
    this.test++;
};
这给了我完全不同的输出

bar this: 0 proto: 0 
bar this: 1 proto: 0 
bar this: 1 proto: 0 
baz this: 1 proto: 0
this.test不应该引用Foo-prototype属性吗?这到底是怎么回事

编辑:

此外,将行更改为
Foo.prototype.test=this.test++
还生成第二个输出,我不知道为什么

编辑2:


第一次编辑的解决方案是后缀和前缀。前缀增量产生第一个输出。

将引用函数的当前实例,而不是原型。

第一种情况:

您只增加了prototype变量,该变量将由prototype对象的所有实例共享

这里需要注意的重要一点是,当您使用
this.test
访问
test
时,在第一种情况下,JavaScript尝试在
this
中查找
test
(当前对象)。它找不到它,在原型链中向上爬。它在
Foo.prototype
中查找
test
,并返回该值。这就是为什么
this.test
Foo.prototype.test
得到相同的值

第二种情况:

您正在增加此测试的
this.test++
可以这样理解

this.test = this.test + 1
Foo.prototype.deleteTest = function () {
    delete this.test;
}

...
...
bar.deleteTest();
bar.getTest('bar');
现在,它从pototype链中获取
test
的值(
Foo.prototype.test
将被使用,它是0),向其中添加1,并将结果存储在当前对象的
test
成员中。因此,您正在
中创建一个名为
test
的新成员。这就是为什么它的值不同于
Foo.prototype.test

您可以通过再添加一个方法来确认这一点,如下所示

this.test = this.test + 1
Foo.prototype.deleteTest = function () {
    delete this.test;
}

...
...
bar.deleteTest();
bar.getTest('bar');

现在
bar.getTest
将打印
0
,因为我们使用
deletetetest()
中删除了
test
。因此,它将在
Foo.prototype
中找到
test
,即0。

正确。但是如果当前实例没有属性
test
,它不应该解析为原型的
test
?否则,
this.test
将是
undefined
,递增
undefined
将给出
NaN
原型具有该属性,因此所有实例都继承该属性,但它们有自己的实例。我不相信这是真的。否则第一次输出就不会发生。(即,更改原型的测试属性值不会更改对象的测试属性)在对象拥有自己的实例之前,它会自动使用原型的实例。一旦你设置了它自己的实例,它就会继续使用它。我明白了。我不知道
this.test++
等同于
this.test=this.test+1
。如果以这种方式查看,输出是有意义的。谢谢还有一个问题
Foo.prototype.test=(this.test++)
生成第二个输出。。。为什么?@moesef因为,您正在输入
this.test
并在递增到
Foo.prototype.test
之前分配值。(请记住:var++是后缀运算符)。因此,
Food.prototype.test
的值将减少一个。尝试
Foo.prototype.test=++this.test,您将能够理解其中的区别:)是的。我试过了。这改变了我的期望。谢谢你的帮助!