Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS class without constant reference to "this" for member access

My typical JS class structure looks like this:

MyClass = function(args)
{
   this.myProp1 = undefined;
   this.myProp2 = args[0];
   //...more member data 

   this.foo = function()
   {
       return this.myProp1 + this.myProp2; //<- the problem.
   }
   //...more member functions
}

//if MyClass extends a superclass, add the following...
MyClass.prototype = Object.create(MySuperClass.prototype);
MyClass.prototype.constructor = MyClass;

...My ongoing annoyance with JS is that I seem to have to use this continuously in member functions in order to access the properties of the very same object to which those functions belong. In several other languages e.g. C# & Java, this may be safely omitted when member functions are working with member data in the same class / instance. (I realise that JS is structured fundamentally differently due to it being designed as a prototypal rather than a hierarchical inheritance language.)

To put the question another way: Is there any way to make the unspecified scope NOT point to window, but rather to the current, local value of this?

P.S. I am guessing this is a language limitation, but thought I'd check again anyway.

like image 553
Engineer Avatar asked Oct 01 '22 05:10

Engineer


2 Answers

In several other languages e.g. C# & Java, this may be safely omitted when member functions are working with member data in the same class / instance. (I realise that JS is structured fundamentally differently due to it being designed as a prototypal rather than a hierarchical inheritance language.)

It's not about the inheritance chain, which is rather static in js as well. It's about JS being a dynamic language, with the global scope being able to add new variables at will, and objects being amendable with arbitrary properties.

So it's just not really possible to make an identifier dynamically resolve to either a local variable or an object property, and we want to distinguish explicitly between them every time by using property accessors for property access.

Is there any way to make the unspecified scope NOT point to window, but rather to the current, local value of this?

The "unspecified scope" is the local scope, which is statically determined and optimized. To make it point to an object (and fall back to variables if the property is not found), you can use the with statement. However, due to this ambiguity it's not only slow, but also considered bad practise - the lookup (of variables) can be influenced by non-local code (that interacts with the instances) which breaks encapsulation and is a maintainability issue.

My typical JS class structure …

Of course you could also change that, and use local variables that are accessed via closure as members instead (see also Javascript: Do I need to put this.var for every variable in an object?). This solves the problems with this, but is also a bit slower (though probably still faster than with).

like image 139
Bergi Avatar answered Oct 17 '22 22:10

Bergi


There is a keyword which partially does what you want: with but it is highly not recommended to use it, because ambiguous in some cases.

If you access a non existing member it will fallback to the window object. So what you could do is declare all the properties you are going to use later and then declare a with statement.

If I had the choice you have, I'd probably change my mind about skipping this or if you can, use another language.

like image 31
axelduch Avatar answered Oct 17 '22 21:10

axelduch