```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 <[email protected]>
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 <[email protected]>
> 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 <[email protected]>
>> 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
>>> [email protected]
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss