Re: Proposal For A New Alternative Keyword To “this” For Classes

guest271314 guest271314 at gmail.com
Tue Mar 12 20:49:53 UTC 2019


```class RequestManager {
  __THIS__(method) {
    return new Proxy(method, {
      apply: (target, thisArg, argumentsList) => {
        return method.apply(thisArg, [...argumentsList, {
          THIS: this
        }])
      }
    })
  }
  constructor() {
    this.successMessage = "Xhr successful.";
  }
  makeRequest() {
    var oReq = new XMLHttpRequest();
    oReq.addEventListener("load", this.__THIS__(this.responseHandler));
    oReq.open("GET", "data:,");
    oReq.send();
  }

  responseHandler(e, {THIS} = {}) {
    console.log(this, e);
    window.alert(THIS.successMessage)
  }
}

var reqManager = new RequestManager();

reqManager.makeRequest();```

On Mon, Mar 11, 2019 at 8:59 AM john larson <johnlarsondev1 at gmail.com>
wrote:

> First of all, thank you all for taking the time to review the proposal and
> sharing your valuable opinions. I would like to note that the proposal aims
> not to add a new capability that was not possible to do before but rather
> move the standard forward on the way for a modern, better and easier to use
> language for all the developers. Advancements of the language, or any
> language in that matter, throughout the last decade also followed a similar
> path because we were already able to do everything in one way or the other.
> We actually strive for the same thing, a better Javascript.
>
>
>
> That being said, let me try to clarify my proposal further by walking you
> through my thought process:
>
>
>
> Normally if I try to write a class similar to the sample code I have given
> in my first email using an object oriented programming language like Java,
> C# etc., I would be writing something similar to the following:
>
>
>
>     class RequestManager
>
>     {
>
>         string successMessage = "Xhr successful.";
>
>
>
>         void makeRequest()
>
>         {
>
>             var oReq = new XMLHttpRequest();
>
>             oReq.addEventListener("load", responseHandler);
>
>             oReq.open("GET", "*www.google.com*
> <#m_-2222847355274947397_inbox/_blank>");
>
>             oReq.send();
>
>         }
>
>
>
>         void responseHandler()
>
>         {
>
>             window.alert(successMessage);
>
>         }
>
>     }
>
>
>
> As you can see, I do not even have to use a special keyword for referring
> to methods from inside the class. Because they are already in lexical
> scope. Now, if this can be accomplished in Javascript without hitting
> some limitation/restriction due to the current state of the language, I
> think it would be the ideal solution. (This limitation might be the class
> syntax being just a syntactical sugar or some other reason that I cannot
> foresee right now and that would require a breaking change.) And I would
> happily change the proposal that way: “A no-keyword alternative for the
> “this””. If I should summarize this approach, I can say that every method
> of the class is going to assume the behavior we now have with arrow
> functions, but without requiring the use of the “this” and the arrow
> function syntax.
>
>
>
> As contrary to the ideal solution, the last thing I would want would be to
> use a context-dependant keyword like the “this” to refer to
> methods/properties of the object and then try to set the context right by
> using binding or arrow functions. This referral should be lexical, not
> context-dependant. If I have the intent of referring to the instance
> method/property, that intent should manifest itself right there where I am
> using this method/property. I shouldn’t be looking at if this takes place
> inside an arrow function, or if the enclosing method is called with a
> binding or not. Why should I care about the enclosing of the call, right?
>
> By the way, MDN also mentions the following about the use of arrow
> functions: “Arrow function expressions are ill suited as methods”.
>
> *@Yulia:* Thanks for pointing out the decorator approach. But that also
> seems to deal with the enclosing and tries to solve the problem with a
> “context binding” approach. The only difference is the way it determines
> the binding. I am against this binding approach all together. Only the
> lexical scope of the code should be taken into consideration.
>
>
>
> So far, I have laid out what I think the ideal solution is and what I
> think the problematic state we are in right now. And as a middle-ground,
> in case the ideal solution cannot be applied, I proposed a new keyword to
> use instead of the “this” so that it will always refer to the instance,
> regardless of execution context binding. In which case, when you replace
> the “this” in the problematic sample code in my initial email, it will work
> just fine. Let’ assume for the sake of this example that the new keyword is
> “self”:
>
>
>
> class RequestManager{
>
>
>
>     constructor(){
>
>         *self*.successMessage = "Xhr successful.";
>
>     }
>
>
>
>
>
>     makeRequest() {
>
>         var oReq = new XMLHttpRequest();
>
>         oReq.addEventListener("load", *self*.responseHandler);
>
>         oReq.open("GET", "*www.google.com*
> <#m_-2222847355274947397_inbox/_blank>");
>
>         oReq.send();
>
>     }
>
>
>
>     responseHandler() {
>
>         window.alert(*self*.successMessage);
>
>     }
>
> }
>
>
>
> var reqManager = new RequestManager();
>
> reqManager.makeRequest();
>
>
>
> As you can see, self.responseHandler will always point to the
> responseHandler method no matter whether the enclosing is a method, an
> arrow function or if it is called using a bind syntax or not.
>
> I would be happy to further address your concerns about this explanation
> if you have any.
>
>
>
> On Sun, Mar 10, 2019 at 10:30 PM guest271314 <guest271314 at gmail.com>
> wrote:
>
>> This is probably not the pattern that is being proposed though outputs
>> the expected result
>>
>>     ```class RequestManager {
>>       constructor() {
>>         this.successMessage = "Xhr successful.";
>>         RequestManager.THIS = this;
>>       }
>>
>>       makeRequest() {
>>         var oReq = new XMLHttpRequest();
>>         oReq.addEventListener("load", this.responseHandler);
>>         oReq.open("GET", "");
>>         oReq.send();
>>       }
>>
>>       responseHandler(e) {
>>         console.log(e, this); // `e`: event, `this`: XMLHttpRequest
>> instance
>>         console.log(RequestManager.THIS.successMessage);
>>       }
>>
>>     }
>>
>>     var reqManager = new RequestManager();
>>
>>     reqManager.makeRequest();```
>>
>> On Sat, Mar 9, 2019 at 11:42 AM john larson <johnlarsondev1 at gmail.com>
>> wrote:
>>
>>> *Summary of the problem:*
>>>
>>> “this” keyword in Javascript is context dependent. And this is one of
>>> the culprits of most subtle and latent errors in Javascript. Moreover, use
>>> of “this” cannot be avoided if we are using classes and trying to reference
>>> instance properties.
>>>
>>> When “this” is used in callback functions or in functions given
>>> to forEach as argument, IDEs rightfully cannot raise any design-time
>>> errors, giving developers the false sense of security, but we get run-time
>>> errors because “this” is undefined.
>>>
>>> There seem to be two work-arounds:
>>>
>>> 1.      Using arrow functions
>>>
>>> 2.      Using .bind(this) syntax
>>>
>>> Just assuming we forgot to use an arrow function or a .bind(), the IDE
>>> will not be able to raise an error and we will encounter the error in
>>> run-time.
>>>
>>>
>>>
>>> *What I propose:*
>>>
>>> I am proposing a new keyword that will be the alternative of "this" and
>>> will always point to the instance of the class. The name of the new keyword
>>> can be chosen with consensus from the community such that it would
>>> minimize/eliminate collision in existing codebases.
>>>
>>>
>>>
>>> Here is a sample js code:
>>>
>>>
>>>
>>> class RequestManager{
>>>
>>>
>>>
>>>     constructor(){
>>>
>>>         this.successMessage = "Xhr successful.";
>>>
>>>     }
>>>
>>>
>>>
>>>
>>>
>>>     makeRequest() {
>>>
>>>         var oReq = new XMLHttpRequest();
>>>
>>>         oReq.addEventListener("load", this.responseHandler);
>>>
>>>         oReq.open("GET", "www.google.com");
>>>
>>>         oReq.send();
>>>
>>>     }
>>>
>>>
>>>
>>>     responseHandler() {
>>>
>>>         window.alert(this.successMessage);
>>>
>>>     }
>>>
>>> }
>>>
>>>
>>>
>>> var reqManager = new RequestManager();
>>>
>>> reqManager.makeRequest();
>>>
>>>
>>>
>>> This piece of code will alert “undefined” because “this” is undefined in
>>> the callback function in strict mode.
>>>
>>> Now let’s assume a new keyword is used insetead of “this” that will
>>> always point to the class instance.
>>>
>>> As per its implementation, as described on
>>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
>>> :
>>>
>>> *“JavaScript classes, introduced in ECMAScript 2015, are primarily
>>> syntactical sugar over JavaScript's existing prototype-based inheritance.
>>> The class syntax does not introduce a new object-oriented inheritance model
>>> to JavaScript.”*
>>>
>>> So with the new keyword introduced, behind the scenes, previous class
>>> could be interpreted as a piece of code along the lines of:
>>>
>>>
>>>
>>> var RequestManager = function () {
>>>
>>>     var self = this;
>>>
>>>     self.successMessage = "Xhr successful";
>>>
>>>
>>>
>>>     self.makeRequest = function () {
>>>
>>>         var oReq = new XMLHttpRequest();
>>>
>>>         oReq.addEventListener("load", responseHandler);
>>>
>>>         oReq.open("GET", "www.google.com");
>>>
>>>         oReq.send();
>>>
>>>     };
>>>
>>>
>>>
>>>     var responseHandler = function () {
>>>
>>>         window.alert(self.successMessage);
>>>
>>>     };
>>>
>>> };
>>>
>>> var reqManager = new RequestManager();
>>>
>>>
>>>
>>> reqManager.makeRequest();
>>>
>>>
>>>
>>> I believe this way, we would not have to resort to work-arounds for such
>>> a fundamental construct of the language and this would ease developers’
>>> lives as someone forgetting to have used an arrow function or the
>>> .bind(this) syntax will not be a problem anymore.
>>>
>>>
>>>
>>> Best Regards,
>>>
>>> John
>>>
>>>
>>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=icon> Virus-free.
>>> www.avast.com
>>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=link>
>>> <#m_-2222847355274947397_m_-8918587750585472385_m_-8001099771182452640_m_-1339185979708762546_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190312/dbe3b700/attachment-0001.html>


More information about the es-discuss mailing list