为了账号安全,请及时绑定邮箱和手机立即绑定

原型上定义的 Javascript 属性

原型上定义的 Javascript 属性

眼眸繁星 2023-10-20 16:52:07
我有一个非常简单的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 1cb.Work();// shows 1 (Q: Why is this not printed 2 ?)现在上面的代码为 this.jobs 打印了 1 次。我期望由于属性“jobs”是在原型上定义的,因此它将是一个共享的属性(并且每个实例都不是真正的不同副本)。但事实似乎并非如此。我的理解哪里错了,我错过了什么?
查看完整描述

4 回答

?
达令说

TA贡献1821条经验 获得超6个赞

通过将其添加到原型中,您可以将其作为实例方法/属性使用。为了让它按照您想要的方式运行,您需要将其直接添加到 Work:


Worker.jobs = 0;

Worker.Work = function () {

    ++this.jobs;

    return this.jobs;

}

那么你甚至可以这样做:


Worker.prototype.work = () => {

    console.log("jobs finished", this.name, Worker.Work());

}


查看完整回答
反对 回复 2023-10-20
?
Qyouu

TA贡献1786条经验 获得超11个赞

您调用的函数位于原型对象中。但它所指的“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);

}


查看完整回答
反对 回复 2023-10-20
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

“this”的使用是指上下文(闭包)。要访问共享属性,您应该使用“prototype”来代替,以按预期工作:


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 ?)


查看完整回答
反对 回复 2023-10-20
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

当您读取this.jobs属性时,查找首先发生在对象实例本身作为自己的属性上,当找不到它时,查找发生在原型链上。


因此,由于该jobs属性是在初始化为 的原型上找到的0,因此该值是从原型中读取的。


当您递增 时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


另一方面,如果您直接更改原型上的属性,您可以看到更改也反映在第二个实例上:


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


查看完整回答
反对 回复 2023-10-20
  • 4 回答
  • 0 关注
  • 96 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信