Skip to content
Advertisement

Why declare/initialize a same property both inside and outside of constructor?

From Classes on mdn web docs:

Public field declarations

JavaScript

Aren’t the height and width outside of the constructor meaningless since they’re always overwritten in the constructor?

What’s the significance of the height and width declaration/initialization outside of constructor in this case?
Are they used/reachable by any means?

Advertisement

Answer

The properties are only declared once (outside the constructor); if you didn’t have those declarations, there’d be no declarations for those properties (they’d be created by assignment instead). Public property declarations (aka “public class fields”) are optional, but can help avoid shape changes in objects (which improves efficiency) and/or reduce the analysis JavaScript engines need to do on the object being created to avoid shape changes. Basically, they provide a declarative (rather than imperative [step-by-step]) means of saying (in this case) that Rectangle objects always have a height and width property. While the JavaScript engine can figure that out using analysis of the constructor code, the declarations mean it doesn’t have to worry about that (for those properties).

Aren’t the height and width outside of the constructor meaningless since they’re always overwritten in the constructor?

The initializer (= 0) on the height property is pointless, yes, since it gets unambiguously overwritten by the code in the constructor and the assignment doing so is the first statement in the constructor. If it weren’t the first statement, then code in the constructor would be able to observe the 0 in height prior to the assignment.

Are [the height and width declaration/initialization outside of constructor] used/reachable by any means?

They could be used by subsequent class field initializers. For instance, this is valid:

JavaScript

It’s probably also worth pointing out that there’s a difference if the class is a subclass: When you use the declaration syntax, the property is created via “define” semantics (as though you used the Object.defineProperty function), whereas if you just assign to it you’re using assignment semantics. That matters if the superclass also defined the property:

JavaScript

Notice that example is an accessor property on super1 (via inheritance from its prototype), but it’s a data property on sub1 because it was redeclared by Sub. If Sub had just assigned to it, it would have just used the property Super created:

JavaScript

Notice that now, it’s an accessor property on both sub1 and super1 (and that when Sub did its assignment, the setter code in Super.example ran).


TL;DR – I would keep the declarations for clarity and potential efficiency, but remove the = 0 initializer on height, since that value is clearly never meant to be used.

Advertisement