开发者问题收集

向原型添加 getter / setter

2015-12-22
440

在下面这段代码中,我尝试向原型添加 getter 和 setter。

function Car(make, model, year) {
    this.make = make;
    this.model = model;
    this.year = year;
    this.displayCar = displayCar;
}

function displayCar() {
    console.log("A Beautiful " + this.year + " " + this.color + " " + this.make + " " + this.model);
}

var c1 = new Car("Ford", "Mustang", 1969);
var c2 = new Car("Skoda", "Octavia", 1999);

var p = Car.prototype;
Object.defineProperty(p, "color", {
    get: function() {return this.color},
    set: function(c) {this.color = c}
    });

c2.color = "White";

c2.displayCar();

有人能帮我理解为什么在第 18 行出现此错误吗:

 Uncaught RangeError: Maximum call stack size exceeded

谢谢。

2个回答

我认为您必须对内部属性使用不同的名称(在我的测试中有效),也许使用 _color

Object.defineProperty(p, "color", {
    get: function() {return this._color},
    set: function(c) {this._color = c}
    });
Joseph Young
2015-12-22

问题出在这些行中:

var p = Car.prototype;
Object.defineProperty(p, "color", {
    set: function(c) {this.color = c} // Setter
});

c2.color = "White";

解释:

这里发生的事情是,您将 c2.color 设置为“白色”。此触发器是您之前定义的设置器。此设置器再次将 this.color 设置为“白色”,从而再次调用设置器。依此类推...直到超出堆栈大小。

So, you're getting stuck in an infinite recursion problem.

如何解决

此问题的一个可能解决方案是将“color”属性的值存储在另一个属性中,如下所示:

var p = Car.prototype;
Object.defineProperty(p, "color", {
    get: function() {return this.color2},
    set: function(c) {this.color2 = c}
});

c2.color = "White";

c2.color // White!

希望有帮助!!;)

BrainOverflow
2015-12-22