I write JS (well, EcmaScript), but only relatively rarely.
When writing on a member function for an object, I naturally often use other member variables and functions multiple times; but I tend to avoid defining my own globals, and no less importantly, I make an effort to avoid aliasing globals with members I define.
Given that state of affairs, I’m annoyed by having to use this
all the time, e.g.:
this.memberA = this.methodB(someInputParam, this.memberC);
I would really like to just say:
memberA = methodB(someInputParam, memberC);
and have memberA
, methodB
and memberC
be looked up first in the scope of this
, then in the global scope.
Can that be done?
2
Answers
Using
this
has own benefits in terms of scoping, you can declare any parameters and local variables and they won’t clash withthis
‘ props. Otherwise you could use so called "hard objects", I was using them for years with success.Answerting the OP’s questions:
Can you elaborate on the difference between the members in the "assign" statement and the other members?
All public members should be assigned to
this
to be available on the instance.Can I do something similar without defining a constructor?
No. The pattern is about using only a constructor to build your instance. All variables inside it are private, the public ones are assigned to
this
. Otherwise there’swith
statement which isn’t recommended.You can use a mixin pattern to gradually enhance your instances with other instances.
There is no sensible, idiomatic, and ergonomical way to do this. Nor is it likely to happen in the future. Any solution would be a huge trade-off in terms of readability, maintainability, and hackyness.
The reason is that when trying to reference an identifier, JavaScript would always use the scope resolution, while referencing an object’s property is different to that. Any change to such mechanics would need to go against fundamental design of JS, thus lead to sacrificing features and code clarity for very little (if any) benefit.
It is also unlikely this would ever be revised in JavaScript, as it would still require to deal with legacy code.
The best bet here is to write a plugin for an existing transpiler that changes to check
this
first then the identifier. So, fromto
However, I would advise against doing even that. The benefit is too small and the risk too great.
Consider using a proper linter which would tell you if you use an undefined variable (in cases where you missed the
this
) and configure your editor to show identifiers and properties differently, to make it easy to distinguish at a glance which one of the two you have. If you use any type checking option (like TypeScript or Flow or others), there would also be an error whenbar
andthis.bar
(assuming both exist) are of different types but used in the wrong place.