我是Javascript的新手,想知道如何修改原型中的公共变量。
function Thing (val)
{
this.x = val;
this.addToX = function (valIn)
{
this.x += valIn;
};
}
function ChildThing ()
{
this.y = 55;
}
ChildThing.prototype = new Thing(10);
var frank = new ChildThing();
console.log("out1: " + frank.x);
frank.addToX(10);
console.log("out2: " + frank.x);
此代码获取原型x中的值10,并在addToX函数中将其加10。新的x值存储在顶级对象中,而不是替换原型中的当前x值。
有没有办法覆盖原型中的现有x,或者我使用Javascript错误了吗?
答案 0 :(得分:1)
这取决于。在原型上改变x
会有什么意义?通常,您不希望更改共享属性。但我想可能有一个用例(生成新的id?)。
至于问题:你可以这样做:
this.addToX = function(valIn) {
ChildThing.prototype.x += valIn;
};
我再也不建议这样做。
编辑您可以通过在将原型设置为原型之前定义原型而不引用子项来制作它,即
var my_proto = new Thing(10);
ChildThing.prototype = my_proto;
然后
this.addToX = function(valIn) {
my_proto.x += valIn;
};
或者你甚至可以玩the singleton pattern。
答案 1 :(得分:0)
您似乎想要的东西与 static 成员在古典语言中非常相似。在对象实例上调用方法并使该方法修改其范围之外的其他对象的状态是非常误导的。因此,我相信你完全没有依赖原型来做这种行为。这是你可以做些什么来模仿静态成员。
function SomeClass() {}
SomeClass.staticMember = 'initial value';
SomeClass.changeStaticMember = function (val) { this.staticMember = val; };
SomeClass.changeStaticMember('another value');
我相信上面的代码不那么神秘,而且更能传达行为。但是,如果您仍希望通过原型在实例之间共享可变值,则可以简单地避免将属性直接写为原始值,而是将其包装在如下所示的可变共享对象中。请注意,整个继承层次结构将共享相同的x
值。
//Mutable class to encapsulate the value of X
function XValue(val) {
this.value = val;
}
XValue.prototype = {
constructor: XValue,
valueOf: function () { return this.value; },
set: function (val) { this.value = val; },
add: function (val) { this.value += val; }
};
function Thing(x) {
this.x = x;
}
Thing.prototype = {
constructor: Thing,
_x: new XValue(), //shared mutable object representing the value of X
get x() { return this._x.valueOf(); },
set x(val) { this._x.set(val); },
addToX: function (val) { this._x.add(val); }
};
function ChildThing() {
Thing.call(this, 10); //call parent constructor
}
ChildThing.prototype = Object.create(Thing.prototype);
//helper for snippet
function log(text) {
var span = document.createElement('span');
span.innerHTML = text;
document.body.appendChild(span);
document.body.appendChild(document.createElement('br'));
}
var ct = new ChildThing();
ct.addToX(10);
log('ct.x → ' + ct.x);
log('Thing.prototype.x → ' + Thing.prototype.x);