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* <#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* <#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 <guest271...@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 <johnlarsond...@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_-8918587750585472385_m_-8001099771182452640_m_-1339185979708762546_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> >> _______________________________________________ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss