esi*_*gel 17 javascript oop inheritance
我在尝试让类变量在javascript中工作时遇到了一些麻烦.
我以为我理解了原型继承模型,但显然不是.我假设由于原型将在对象之间共享,因此它们的变量也是如此.
这就是为什么这段代码让我困惑的原因.
实现类变量的正确方法是什么?
function classA() {};
classA.prototype.shared = 0;
a = new classA;
//print both values to make sure that they are the same
classA.prototype.shared;
a.shared;
//increment class variable
classA.prototype.shared++;
//Verify that they are each 1 (Works)
classA.prototype.shared;
a.shared;
//now increment the other reference
a.shared++;
//Verify that they are each 2 (Doesn't Work)
classA.prototype.shared;
a.shared;
Run Code Online (Sandbox Code Playgroud)
更新:所以似乎每个人都在确认通过递增实例的变量这一事实我们不会影响原型.这很好,这是我在我的例子中记录的内容,但这不是在语言设计中出现错误吗?为什么这种行为是可取的?我觉得奇怪的是,当实例的var未定义时,我们遵循原型的隐藏链接,我们得到var的值,但我们将它复制到实例对象中.
我也明白这不是java/c ++/ruby/python,它是一种不同的语言.我只是好奇为什么这种行为可能会很好.
Dan*_*ley 15
静态(类级别)变量可以像这样完成:
function classA(){
//initialize
}
classA.prototype.method1 = function(){
//accessible from anywhere
classA.static_var = 1;
//accessible only from THIS object
this.instance_var = 2;
}
classA.static_var = 1; //This is the same variable that is accessed in method1()
Run Code Online (Sandbox Code Playgroud)
由于javascript处理原型的方式,你的输出看起来很奇怪.调用任何方法/ retreiving实例化对象的变量首先检查实例,然后检查原型.即
var a = new classA();
classA.prototype.stat = 1;
// checks a.stat which is undefined, then checks classA.prototype.stat which has a value
alert(a.stat); // (a.stat = undefined, a.prototype.stat = 1)
// after this a.stat will not check the prototype because it is defined in the object.
a.stat = 5; // (a.stat = 5, a.prototype.stat = 1)
// this is essentially a.stat = a.stat + 1;
a.stat++; // (a.stat = 6, a.prototype.stat = 1)
Run Code Online (Sandbox Code Playgroud)
I assumed that since prototypes will be shared between objects then so will their variables.
Run Code Online (Sandbox Code Playgroud)
它们是,但是这个:
a.shared++
Run Code Online (Sandbox Code Playgroud)
没有做你认为它正在做的事情.它实际上(大约)糖语法:
(a.shared= a.shared+1)-1
Run Code Online (Sandbox Code Playgroud)
(-1表示返回预增量值,而不是您实际使用的是retrun值,但仍然.)
所以这实际上是对a.shared做了一个分配.当您分配给实例成员时,您始终会写入该实例自己的成员,而不是触及任何原型的任何成员.这跟说:
classA.prototype.shared= 1;
a.shared= 2;
Run Code Online (Sandbox Code Playgroud)
所以你的新a.shared会隐藏prototype.shared而不会改变它.classA的其他实例将继续显示原型的值1.如果删除a.shared,您将再次能够看到隐藏在其后面的原型变量.