Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript, extending ES6 class setter will inheriting getter

In Javascript, with the following illustration code:

class Base {
   constructor() {  this._val = 1   }
   get val()     { return this._val }
}

class Xtnd extends Base {
   set val(v)    { this._val = v }
}

let x = new Xtnd();
x.val = 5;
console.log(x.val);  // prints 'undefined'

the instance x will not inherit get val()... from Base class. As it is, Javascript treat the absence of a getter, in the presence of the setter, as undefined.

I have a situation in which I have many classes that all have the exact same set of getters but unique setters. Currently, I simply replicate the getters in each class, but I'm refactoring and want to eliminate the redundant code.

Is there a way to tell JS to keep the getter from the base class, or does anyone have an elegant solution to this problem?

like image 983
codechimp Avatar asked Dec 02 '18 21:12

codechimp


People also ask

Are getters and setters inherited?

Do the setter/getter methods always affect only values in objects where they are declared, even called from a subclass by inheritance? You cannot inherit the methods but not the variables. You inherit everything from the parent class. Private just means that you cannot directly access it, but it is still there.

How is inheritance implemented in ES6?

This can be done using the extends and super keywords. We use the extends keyword to implement the inheritance in ES6. The class to be extended is called a base class or parent class. The class that extends the base class or parent class is called the derived class or child class.

Can we use getter and setter in same class?

Yes, the methods of your class should call the getters and setters. The whole point in writing getters and setters is future proofing. You could make every property a field and directly expose the data to the users of the class.

Can getter and setter have same name JavaScript?

“Another thing to keep in mind when using getter (and setter) methods is that properties cannot share the same name as the getter/setter function.”


1 Answers

This limitation is due to how JavaScript treats property accessors behind the scenes. In ECMAScript 5, you end up with a prototype chain that has a property descriptor for val with a get method defined by your class, and a set method that is undefined.

In your Xtnd class you have another property descriptor for val that shadows the entire property descriptor for the base class's val, containing a set method defined by the class and a get method that is undefined.

In order to forward the getter to the base class implementation, you'll need some boilerplate in each subclass unfortunately, but you won't have to replicate the implementation itself at least:

class Base {
   constructor() {  this._val = 1   }
   get val()     { return this._val }
}

class Xtnd extends Base {
   get val()     { return super.val }
   set val(v)    { this._val = v }
}

let x = new Xtnd();
x.val = 5;
console.log(x.val);  // prints '5'
like image 129
Patrick Roberts Avatar answered Sep 23 '22 03:09

Patrick Roberts