javascript:class.property vs class.prototype.property模拟静态属性
我一直试图在javascript中模拟静态属性。 有几处提到,class.prototype.property将在继承自该类的所有对象中保持静态。但我的POC却不这么说。请看一看: 使用Class.prototype.propertyjavascript:class.property vs class.prototype.property模拟静态属性,javascript,static,prototype,Javascript,Static,Prototype,我一直试图在javascript中模拟静态属性。 有几处提到,class.prototype.property将在继承自该类的所有对象中保持静态。但我的POC却不这么说。请看一看: 使用Class.prototype.property //Employee class function Employee() { this.getCount = function(){ return this.count; }; this.count += 1;
//Employee class
function Employee() {
this.getCount = function(){
return this.count;
};
this.count += 1;
}
Employee.prototype.count = 3;
var emp = [], i;
for (i = 0; i < 3; i++) {
emp[i] = new Employee();
console.log("employee count is "+ emp[i].getCount());
}
/*Output is:
employee count is 4
employee count is 4
employee count is 4*/
//Employee class
function Employee() {
this.getCount = function(){
return Employee.count;
};
Employee.count++;
}
Employee.count = 3;
var emp = [], i;
for (i = 0; i < 3; i++) {
emp[i] = new Employee();
console.log("employee count is "+ emp[i].getCount());
}
/*Output is:
employee count is 4
employee count is 5
employee count is 6*/
//员工类
职能雇员(){
this.getCount=函数(){
返回这个.count;
};
这是1.count+=1;
}
Employee.prototype.count=3;
var-emp=[],i;
对于(i=0;i<3;i++){
emp[i]=新员工();
log(“员工计数为”+emp[i].getCount());
}
/*输出为:
雇员人数是4
雇员人数是4
雇员人数是4*/
我的问题#1:如果这是静态的,那么count的值不应该是4、5、6等等,因为所有对象共享相同的count变量吗
然后我用Class.prototype做了另一个POC,我认为这是静态的
使用Class.property
//Employee class
function Employee() {
this.getCount = function(){
return this.count;
};
this.count += 1;
}
Employee.prototype.count = 3;
var emp = [], i;
for (i = 0; i < 3; i++) {
emp[i] = new Employee();
console.log("employee count is "+ emp[i].getCount());
}
/*Output is:
employee count is 4
employee count is 4
employee count is 4*/
//Employee class
function Employee() {
this.getCount = function(){
return Employee.count;
};
Employee.count++;
}
Employee.count = 3;
var emp = [], i;
for (i = 0; i < 3; i++) {
emp[i] = new Employee();
console.log("employee count is "+ emp[i].getCount());
}
/*Output is:
employee count is 4
employee count is 5
employee count is 6*/
//员工类
职能雇员(){
this.getCount=函数(){
返回Employee.count;
};
Employee.count++;
}
Employee.count=3;
var-emp=[],i;
对于(i=0;i<3;i++){
emp[i]=新员工();
log(“员工计数为”+emp[i].getCount());
}
/*输出为:
雇员人数是4
员工人数为5人
雇员人数是6*/
我的问题2:我没有看到class.property被直接使用。记住我上面的代码,javascript中的静态变量究竟是如何生成的
还是我把这里的代码写错了?这不是正确的看法吗
我的问题#1:如果这是静态的,那么count的值不应该是4、5、6等等,因为所有对象共享相同的count变量吗
原型属性在实例之间共享,但如果实例有自己的属性副本,它将使用该副本。分配给实例上的属性会给它自己的副本,因此它不再使用原型的副本
+=
、++
和类似的运算符会导致赋值,因此它们也会导致这种行为
考虑:
function Employee() {
}
Employee.prototype.count = 0;
在上面的代码中,内存中有一个对象用于Employee.prototype
。一些ASCII艺术:
+−−−−−−−−−−−−−−−−−−−−+
| Employee.prototype |
+−−−−−−−−−−−−−−−−−−−−+
| count: 0 |
+−−−−−−−−−−−−−−−−−−−−+
现在内存中还有第二个对象,它引用回Employee.prototype
:
+−−−−−−−−−−−−−−−+
| e |
+−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−+
| [[Prototype]] |−−−−−−−−−>| Employee.prototype |
+−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−+
| count: 0 |
+−−−−−−−−−−−−−−−−−−−−+
…由于e
没有自己的名为count
的属性,因此引擎会查看e
的原型以找到它,找到它,并使用该值
然而,当我们这样做时:
var e = new Employee();
e.count += 1; // Or more idiomatically, `++e.count;` or `e.count++;`
为e
实例上的count
赋值e
现在有自己的count
副本:
console.log(e.count);
+−−−−−−−−−−−−−−−+
| e |
+−−−−−−−−−−−−−−−+
| count: 1 | +−−−−−−−−−−−−−−−−−−−−+
| [[Prototype]] |−−−−−−−−−>| Employee.prototype |
+−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−+
| count: 0 |
+−−−−−−−−−−−−−−−−−−−−+
console.log(e.count);
…引擎在e
上查找count
,而不查看原型
您可以在代码中看到这种效果:
function Employee(){
}
Employee.prototype.count=0;
var e=新员工();
console.log(例如hasOwnProperty('count'));//假的
e、 计数+=1;
console.log(例如hasOwnProperty('count'));//真的
console.log(e.count);//1.
console.log(Employee.prototype.count);//0
我一直在使用第二种形式。我认为此
始终是指向determine by run time对象的实例,而您的代码中的Employee
是一个“原型声明”。感谢您的精确解释。当我看到可以通过prototype.properties在javascript中创建静态属性时,我感到非常困惑,而我的代码则不然。因此,Class.prototype.properties基本上是静态的,在这种情况下只更改object.properties。如果我改为使用Employee.prototype.count+=1,那么它将按预期工作。因此,对于一个可靠的静态属性实现,您建议我使用我的第二个代码或您提到的第二种实现方式。再次感谢。@riju:不管怎样,都由你决定。这取决于您希望信息公开的程度。如果使用Employee.count
,并且Employee
是公共的,那么Employee.count
是公共的——任何地方的任何代码都可以更新它。这可能很有用。如果使用模块模式(我的第二个示例),则只有外部作用域函数中的代码可以访问sharedVariable
。实际上,它是您在其中定义的员工的私有代码。您可以将函数添加到Employee.prototype
,只要您在作用域函数中这样做,它们就可以使用sharedVariable
(但其他人不能)。