Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #32412 > unrolled thread
| Started by | Une Bévue <unbewusst.sein@fai.invalid> |
|---|---|
| First post | 2017-01-29 10:18 +0100 |
| Last post | 2017-01-29 15:56 +0100 |
| Articles | 7 — 3 participants |
Back to article view | Back to comp.lang.javascript
ES6 class properties are undefined ? Une Bévue <unbewusst.sein@fai.invalid> - 2017-01-29 10:18 +0100
Re: ES6 class properties are undefined ? Martin Honnen <martin.honnen@gmx.de> - 2017-01-29 12:01 +0100
Re: ES6 class properties are undefined ? Une Bévue <unbewusst.sein@fai.invalid> - 2017-01-29 12:14 +0100
Re: ES6 class properties are undefined ? Martin Honnen <martin.honnen@gmx.de> - 2017-01-29 12:55 +0100
Re: ES6 class properties are undefined ? Une Bévue <unbewusst.sein@fai.invalid> - 2017-01-29 15:50 +0100
Re: ES6 class properties are undefined ? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2017-01-29 14:00 +0100
Re: ES6 class properties are undefined ? Une Bévue <unbewusst.sein@fai.invalid> - 2017-01-29 15:56 +0100
| From | Une Bévue <unbewusst.sein@fai.invalid> |
|---|---|
| Date | 2017-01-29 10:18 +0100 |
| Subject | ES6 class properties are undefined ? |
| Message-ID | <o6kc0n$jep$1@shakotay.alphanet.ch> |
I've a class like that (simplified for clarity):
let SocketService = class SocketService {
constructor(url) {
this.url = url;
this.ws = null;
this.timerID = 0;
this.init();
}
init() {
let that = this;
this.ws = new WebSocket(this.url);
this.ws.onclose = function() {
that.timerID = window.setInterval(that.init, 5000);
};
}
}
when I shut down the WebSocket server in order to test my script
i get : this.url = undefined; (that.url too)
only the first time init() is activated gives the correct value, why ?
it seems "this" is lost...
[toc] | [next] | [standalone]
| From | Martin Honnen <martin.honnen@gmx.de> |
|---|---|
| Date | 2017-01-29 12:01 +0100 |
| Message-ID | <o6ki2m$ek5$1@news.albasani.net> |
| In reply to | #32412 |
On 29.01.2017 10:18, Une Bévue wrote:
> I've a class like that (simplified for clarity):
>
> let SocketService = class SocketService {
> constructor(url) {
> this.url = url;
> this.ws = null;
> this.timerID = 0;
> this.init();
> }
> init() {
> let that = this;
> this.ws = new WebSocket(this.url);
> this.ws.onclose = function() {
> that.timerID = window.setInterval(that.init, 5000);
> };
> }
> }
>
> when I shut down the WebSocket server in order to test my script
> i get : this.url = undefined; (that.url too)
> only the first time init() is activated gives the correct value, why ?
> it seems "this" is lost...
Try whether using
that.timerID = window.setInterval(function() { that.init(); }, 5000);
instead of
that.timerID = window.setInterval(that.init, 5000);
improves things.
[toc] | [prev] | [next] | [standalone]
| From | Une Bévue <unbewusst.sein@fai.invalid> |
|---|---|
| Date | 2017-01-29 12:14 +0100 |
| Message-ID | <o6kiqf$vbn$1@shakotay.alphanet.ch> |
| In reply to | #32414 |
Le 29/01/2017 à 12:01, Martin Honnen a écrit :
> Try whether using
> that.timerID = window.setInterval(function() { that.init(); }, 5000);
Fine, thanks, that works !
Do you have an explanation ?
[toc] | [prev] | [next] | [standalone]
| From | Martin Honnen <martin.honnen@gmx.de> |
|---|---|
| Date | 2017-01-29 12:55 +0100 |
| Message-ID | <o6kl8c$cro$1@news.albasani.net> |
| In reply to | #32415 |
On 29.01.2017 12:14, Une Bévue wrote:
> Le 29/01/2017 à 12:01, Martin Honnen a écrit :
>> Try whether using
>> that.timerID = window.setInterval(function() { that.init(); }, 5000);
>
> Fine, thanks, that works !
>
> Do you have an explanation ?
Your attempt with
that.timerID = window.setInterval(that.init, 5000);
passes the function reference the expression `that.init` gives to
setInterval, it is then executed later in the context of the window
object and not of the SocketService instance you want it to be called
on. My suggestion passes a function reference forming a closure on the
`that` variable and that way setInterval calls the method on the
intended instance and not on the window object.
[toc] | [prev] | [next] | [standalone]
| From | Une Bévue <unbewusst.sein@fai.invalid> |
|---|---|
| Date | 2017-01-29 15:50 +0100 |
| Message-ID | <o6kvgg$mpv$1@shakotay.alphanet.ch> |
| In reply to | #32416 |
Le 29/01/2017 à 12:55, Martin Honnen a écrit : > > Your attempt with > that.timerID = window.setInterval(that.init, 5000); > passes the function reference the expression `that.init` gives to > setInterval, it is then executed later in the context of the window > object and not of the SocketService instance you want it to be called > on. My suggestion passes a function reference forming a closure on the > `that` variable and that way setInterval calls the method on the > intended instance and not on the window object. OK, thanks, crystal clear.
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2017-01-29 14:00 +0100 |
| Message-ID | <1771785.oMNUckLgyt@PointedEars.de> |
| In reply to | #32414 |
Martin Honnen wrote:
> On 29.01.2017 10:18, Une Bévue wrote:
>> let SocketService = class SocketService {
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
DRY.
>> constructor(url) {
>> this.url = url;
>> this.ws = null;
>> this.timerID = 0;
Consider
Object.assign(this, {
url: url,
ws: null,
timerID: 0
});
>> this.init();
>> }
>> init() {
>> let that = this;
>> this.ws = new WebSocket(this.url);
>> this.ws.onclose = function() {
>> that.timerID = window.setInterval(that.init, 5000);
>> };
>> }
>> }
>>
>> when I shut down the WebSocket server in order to test my script
>> i get : this.url = undefined; (that.url too)
>> only the first time init() is activated gives the correct value, why ?
>> it seems "this" is lost...
>
> Try whether using
> that.timerID = window.setInterval(function() { that.init(); }, 5000);
> instead of
> that.timerID = window.setInterval(that.init, 5000);
> improves things.
Things can be improved more (i.e. more efficient) if the function is not
created every time that the event listener is called:
var init = function () { that.init(); };
this.ws.onclose = function () {
that.timerID = window.setInterval(init, 5000);
};
Or, given that ES6 is already being used,
var init = this.init.bind(this);
this.ws.onclose = (function () {
this.timerID = window.setInterval(init, 5000);
}).bind(this);
so that the “that” variable becomes unnecessary. [However, this comes at
the price of flexibility: with .bind() for the event listener, “this” can no
longer be used in it to refer to the object that fired the event. So one
might only want to use the first .bind() here.]
But in fact, this code does not make sense. ISTM that the
window.setInterval() should be window.setTimeout(); at least there should be
a window.clearInterval() in .init() for the window.setInterval() in the
event listener. Otherwise whenever the WebSocket instance fires a “close”
event, new "intervals" will pile up.
--
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Une Bévue <unbewusst.sein@fai.invalid> |
|---|---|
| Date | 2017-01-29 15:56 +0100 |
| Message-ID | <o6kvqd$n1c$1@shakotay.alphanet.ch> |
| In reply to | #32417 |
Le 29/01/2017 à 14:00, Thomas 'PointedEars' Lahn a écrit :
> Martin Honnen wrote:
>
>> On 29.01.2017 10:18, Une Bévue wrote:
>>> let SocketService = class SocketService {
> ^^^^^^^^^^^^^ ^^^^^^^^^^^^^
> DRY.
I thought "let SocketService = ..." is necessary because the file ends
with :
export default SocketService;
i didn't mention that point.
> Or, given that ES6 is already being used,
Yes, I'm using ES6 here (for the first time).
> var init = this.init.bind(this);
>
> this.ws.onclose = (function () {
> this.timerID = window.setInterval(init, 5000);
> }).bind(this);
>
> so that the “that” variable becomes unnecessary. [However, this comes at
> the price of flexibility: with .bind() for the event listener, “this” can no
> longer be used in it to refer to the object that fired the event. So one
> might only want to use the first .bind() here.]
OK.
> But in fact, this code does not make sense. ISTM that the
> window.setInterval() should be window.setTimeout(); at least there should be
> a window.clearInterval() in .init() for the window.setInterval() in the
> event listener. Otherwise whenever the WebSocket instance fires a “close”
> event, new "intervals" will pile up.
There is a clearInterval :
this.ws.onopen = function(message) {
let i = 0;
let c = that.preConnectionRequests.length;
if (!that.timerID || that.timerID > 0) {
window.clearInterval(that.timerID);
that.timerID = 0;
}
again, not metionned at first post.
Thanks !
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web