I was expecting myCar.setWheels = 2
to alter the inherited property, but instead it sets myCar
's local property which shadows inherited one
Well, you've "called" the setter on myCar
, so you are setting its .wheels
property.
If you wanted to alter the inherited property, you need to alter it on the object from which it is inherited:
Car.prototype.setWheels = 2;
(Although I've never seen a car with two wheels)
Notice that usually you'd expect instance properties (.wheels
set in Vehicle
) to be only apparent on instances (like myCar
), not on prototypes. You might consider changing your way of inheritance to the commonly accepted one.
The quote you have read at MDN:
Setting a property to an object creates an own property. The only
exception to the getting and setting behavior rules is when there is
an inherited property with a getter or a setter.
means that an own property will be generated on assignment when there is no setter (but it is a data property or not existing yet). If the property that gets assigned to has a setter defined (either own or inherited), then that setter function will be invoked instead.
Indeed, in your example, no own .setWheels
property is getting created on your myCar
.
What the setter function does it a whole different question. It can create a property (like yours does, by assigning to .wheels
on the current instance, this
), or do anything else; including crazy things like redefining itself.
To get the "expected" behaviour, you could use a local variable to store the number of wheels and use a setter/getter property for it:
function Car() {}
var w = 4; // "local", could be in an IIFE
Object.defineProperty(Car.prototype, "wheels", {
set: function(x) {
w = x; // no property changes/creations involved
},
get: function() {
return w;
}
});
// yourCar inherits 'wheels'
var yourCar = new Car();
yourCar.wheels; // 4
yourCar.wheels = 2; // you've got an odd car
var myCar = new Car();
myCar.wheels; // 2 - what's wrong with my car?!
Here, there is only one property - Car.prototype.wheels
. Assigning to .wheels
on the Car
instances will call the shared setter, which updates the shared variable. Notice that such behaviour is usually undesirable, you don't want one instance affect all others.