Say I have this "class":
function Car()
{
}
Object.defineProperty(Car.prototype, "Make",
{
get:function() { return this._make; },
set:function(value) { this._make = value; }
});
Object.prototype.Drive = function Drive() { console.log("Car.Drive"); }
Now I want to make a "child class" using prototype inheritance:
function Sedan()
{
}
Sedan.prototype = new Car();
Sedan.prototype.constructor = Sedan;
Sedan.prototype.Drive = function Drive() { Car.prototype.Drive.call(this); console.log("Sedan.Drive"); }
Then I can instantiate a car or a sedan, and drive both. Notice how with sedans, Drive also calls base class (Car) Drive:
var car = new Car(); car.Drive(); var carMake = car.Make;
var sedan = new Sedan(); sedan.Drive(); var sedanMake = sedan.Make;
Is it possible to achieve something similar with properties?
Object.defineProperty(Sedan.prototype, "Make",
{
get: function() { return Car.prototype.Make.<<CALL_GETTER>>(this) + " - Sedan"; },
set: function(value) { Car.prototype.Make.<<CALL_SETTER>>(this, value.replace(" - Sedan", "")); }
});
The only idea I could come up with is something like this:
Car.prototype.get_Make = function get_Make() { return this._make; }
Car.prototype.set_Make = function set_Make(value) { this._make = value; }
Object.defineProperty(Car.prototype, "Make",
{
get:function() { return this.get_Make(); },
set:function(value) { this.set_Make(value); }
});
Then the explicit get_Make and set_Make can be overridden similar to Drive. However, this is clunky. Sure, this boilerplate can be extracted into a helper function which defines the get_ and set_ methods and the property in one shot.
function DefineVirtualProperty(obj, name, getter, setter)
{
obj["get_" + name] = getter;
obj["set_" + name] = setter;
Object.defineProperty(obj, name,
{
get:function() { return this["get_" + name](); },
set: function(value) { this["set_" + name](value); }
});
}
DefineVirtualProperty(Car.prototype, "Make", function() { return this._make; }, function(value) { this._make = value; });
However the overriding still looks a big ugly.