简体   繁体   English

原型上定义的 Javascript 属性

[英]Javascript property defined on prototype

I have a very simple JS code as below;我有一个非常简单的JS代码如下;

var Worker = function (name) {
    this.name = name;
}
Worker.prototype.jobs = 0;
Worker.prototype.Work = function () {
    console.log("jobs finished", this.name, ++this.jobs);
}
var ca = new Worker("ca");
var cb = new Worker("cb");
ca.Work();// shows 1
cb.Work();// shows 1 (Q: Why is this not printed 2 ?)

Now the above prints 1 for this.jobs twice.现在上面为 this.jobs 打印 1 两次。 I was expecting that since the property "jobs" is defined on the prototype, it would be a shared one (and not really a different copy for each instance).我期待由于属性“jobs”是在原型上定义的,它将是一个共享的(而不是每个实例的真正不同的副本)。 However that does not seem to be the case.然而,情况似乎并非如此。 Where is my understanding wrong and what am I missing?我的理解哪里错了,我错过了什么?

By adding it to the prototype you've made it available as an instance method/property.通过将其添加到原型中,您可以将其作为实例方法/属性使用。 For it to function how you would like, you need to add it directly to Work:对于 function 怎么想,你需要直接添加到 Work:

Worker.jobs = 0;
Worker.Work = function () {
    ++this.jobs;
    return this.jobs;
}

then you could even do something like this:那么你甚至可以做这样的事情:

Worker.prototype.work = () => {
    console.log("jobs finished", this.name, Worker.Work());
}

The function you are called is in the prototype object.您所称的 function 在原型 object 中。 But the ´this´ it is referring to, is in the child object.但它所指的“this”是在子 object 中。 Only if the property does not exist, this[propertyname] lookup will progress up the prototype chain.只有当属性不存在时,this[propertyname] 查找才会在原型链上进行。

// ++this.jobs is a short for this.jobs = this.jobs +1;
// if the child object is missing this.jobs property, it is fetched from the prototype object. So this assigns the 'jobs' property to current object, but looks it up from the prototype object.
Worker.prototype.Work = function () {
   console.log("jobs finished", this.name, ++this.jobs);
}

When you are reading the this.jobs property, the lookup first happens on the object instance itself as an own property first and when it is not found the look up happens on the prototype chain.当您阅读this.jobs属性时,查找首先发生在 object 实例本身作为自己的属性,当没有找到时,查找发生在原型链上。

So since the jobs property is found on the prototype which is initialized to 0 , the value is read from the prototype.因此,由于在初始化为0的原型上找到了jobs属性,因此从原型中读取该值。

When you increment the this.job , this will create a own property after increment operation, which is why we never see the change in the other instance as the jobs becomes an own property of that particular instance:当您递增this.job时,这将在递增操作后创建一个自己的属性,这就是为什么当jobs成为该特定实例的自己的属性时,我们永远不会看到另一个实例中的更改:

 var Worker = function (name) { this.name = name; } Worker.prototype.jobs = 0; Worker.prototype.Work = function () { console.log("jobs is an own property =>", this.hasOwnProperty("jobs")); ++this.jobs console.log("jobs is now an own property =>", this.hasOwnProperty("jobs")); console.log("jobs finished", this.name, this.jobs); } var ca = new Worker("ca"); var cb = new Worker("cb"); ca.Work();// shows 1 cb.Work();// shows 1

On the other hand if you directly mutate the property on the prototype, you can see that the change is reflected on the second instance as well:另一方面,如果您直接更改原型上的属性,您可以看到更改也反映在第二个实例上:

 var Worker = function (name) { this.name = name; } Worker.prototype.jobs = 0; Worker.prototype.Work = function () { ++Object.getPrototypeOf(this).jobs console.log("jobs finished", this.name, this.jobs); } var ca = new Worker("ca"); var cb = new Worker("cb"); ca.Work();// shows 1 cb.Work();// shows 2

The use of 'this' is refer to context (closure). “this”的使用是指上下文(闭包)。 For access the shared property you should use 'prototype' instead, to work as expected:要访问共享属性,您应该使用“原型”来按预期工作:

var Worker = function (name) {
    this.name = name;
}
Worker.prototype.jobs = 0;
Worker.prototype.Work = function () {
    console.log("jobs finished", this.name, ++Worker.prototype.jobs);
}
var ca = new Worker("ca");
var cb = new Worker("cb");
ca.Work();// shows 1
cb.Work();// shows 1 (Q: Why is this not printed 2 ?)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM