Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #22840 > unrolled thread
| Started by | Alon Melanker <melankeril@gmail.com> |
|---|---|
| First post | 2014-01-28 05:57 -0800 |
| Last post | 2014-01-29 15:39 +0100 |
| Articles | 13 — 7 participants |
Back to article view | Back to comp.lang.javascript
I thought I understood JavaScript till they asked me this on a job interview Alon Melanker <melankeril@gmail.com> - 2014-01-28 05:57 -0800
Re: I thought I understood JavaScript till they asked me this on a job interview Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-01-28 15:58 +0100
Re: I thought I understood JavaScript till they asked me this on a job interview Hans-Georg Michna <hans-georgNoEmailPlease@michna.com> - 2014-01-28 16:38 +0100
Re: I thought I understood JavaScript till they asked me this on a job interview "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2014-01-28 17:25 +0100
Re: I thought I understood JavaScript till they asked me this on a job interview Christoph Michael Becker <cmbecker69@arcor.de> - 2014-01-28 19:00 +0100
Re: I thought I understood JavaScript till they asked me this on a job interview Hans-Georg Michna <hans-georgNoEmailPlease@michna.com> - 2014-01-29 10:22 +0100
Re: I thought I understood JavaScript till they asked me this on a job interview Christoph Michael Becker <cmbecker69@arcor.de> - 2014-01-29 17:34 +0100
Re: I thought I understood JavaScript till they asked me this on a job interview Jim T. <x@y.z> - 2014-01-29 12:45 -0500
Re: I thought I understood JavaScript till they asked me this on a job interview Hans-Georg Michna <hans-georgNoEmailPlease@michna.com> - 2014-01-30 09:09 +0100
Re: I thought I understood JavaScript till they asked me this on a job interview Alon Melanker <melankeril@gmail.com> - 2014-01-29 01:52 -0800
setTimeout() (was: I thought I understood JavaScript till they asked me this on a job interview) Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-01-29 12:59 +0100
Re: I thought I understood JavaScript till they asked me this on a job interview Bjoern Hoehrmann <bjoern@hoehrmann.de> - 2014-01-29 14:30 +0100
Re: I thought I understood JavaScript till they asked me this on a job interview Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-01-29 15:39 +0100
| From | Alon Melanker <melankeril@gmail.com> |
|---|---|
| Date | 2014-01-28 05:57 -0800 |
| Subject | I thought I understood JavaScript till they asked me this on a job interview |
| Message-ID | <b3e79681-ee2f-45bb-bcac-39505315bfde@googlegroups.com> |
function damn() {
this.x = 4;
var y = 3;
setTimeout(function() {alert(this.x); alert(y)}, 100);
this.aa = function() {
alert(this.x);
};
}
aaa = new damn();
aaa.aa();
What would be the output?!
The correct answer should be 4 undefined and 3.
I answered 4 4 3.
The question is why this.x inside setTimeout does not alert 4?
[toc] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-01-28 15:58 +0100 |
| Message-ID | <7998487.AcjmSas2GF@PointedEars.de> |
| In reply to | #22840 |
Alon Melanker wrote:
> function damn() {
> this.x = 4;
> var y = 3;
>
> setTimeout(function() {alert(this.x); alert(y)}, 100);
>
> this.aa = function() {
> alert(this.x);
> };
> }
>
> aaa = new damn();
> aaa.aa();
>
> What would be the output?!
>
> The correct answer should be 4 undefined and 3.
Yes, although there is a race condition and it could be “undefined”, “3”,
and “4” as well. Or a SyntaxError or TypeError exception could be thrown.
> I answered 4 4 3.
>
> The question is why this.x inside setTimeout does not alert 4?
I could tell you (and probably others will, with wrong explanations
in-between), but try debugging first. You will learn more for your next
interview this way.
<http://devtoolsecrets.com/>
<http://PointedEars.de/faq#posting>
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Hans-Georg Michna <hans-georgNoEmailPlease@michna.com> |
|---|---|
| Date | 2014-01-28 16:38 +0100 |
| Message-ID | <1kjfe9dfbkr26pntdongvqpi2e65ushk2t@4ax.com> |
| In reply to | #22841 |
Why is this.x in each of the inner functions not always undefined, since it has never been defined inside those functions? I.e. resulting displays: undefined, undefined, 3 Hans-Georg
[toc] | [prev] | [next] | [standalone]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2014-01-28 17:25 +0100 |
| Message-ID | <XnsA2C3B1411512Aeejj99@194.109.133.133> |
| In reply to | #22842 |
Hans-Georg Michna <hans-georgNoEmailPlease@michna.com> wrote on 28 jan 2014
in comp.lang.javascript:
> Why is this.x in each of the inner functions not always
> undefined, since it has never been defined inside those
> functions?
>
> I.e. resulting displays: undefined, undefined, 3
Not here [chrome]
Try this:
==========================
<script type='text/javascript'>
function damn() {
this.x = 4;
var y = 3;
setTimeout(function() {alert(this.x+'a'); alert(y+'b')}, 100);
this.aa = function() {
alert(this.x+'c');
};
};
var aaa = new damn();
aaa.aa();
</script>
==================================
Then change
aaa.aa();
to
//aaa.aa();
and see what happens.
--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)
[toc] | [prev] | [next] | [standalone]
| From | Christoph Michael Becker <cmbecker69@arcor.de> |
|---|---|
| Date | 2014-01-28 19:00 +0100 |
| Message-ID | <52e7f038$0$9519$9b4e6d93@newsspool1.arcor-online.net> |
| In reply to | #22842 |
Hans-Georg Michna wrote: > Why is this.x in each of the inner functions not always > undefined, since it has never been defined inside those > functions? That is explained in the section "Execution Contexts" of the ECMAScript specification[1]; keyword: ThisBinding. [1] <http://www.ecma-international.org/ecma-262/5.1/#sec-10.3> -- Christoph M. Becker
[toc] | [prev] | [next] | [standalone]
| From | Hans-Georg Michna <hans-georgNoEmailPlease@michna.com> |
|---|---|
| Date | 2014-01-29 10:22 +0100 |
| Message-ID | <5ihhe99i1vccel1sdlg5boqr4t5m1k98di@4ax.com> |
| In reply to | #22850 |
On Tue, 28 Jan 2014 19:00:28 +0100, Christoph Michael Becker wrote: >Hans-Georg Michna wrote: >> Why is this.x in each of the inner functions not always >> undefined, since it has never been defined inside those >> functions? >That is explained in the section "Execution Contexts" of the ECMAScript >specification[1]; keyword: ThisBinding. > >[1] <http://www.ecma-international.org/ecma-262/5.1/#sec-10.3> Thanks! Sorry, but that text is unintelligible to me, because it explains everything in lots of terms that are all unknown to me. It seems I would have to read and memorize the entire document before being able to make sense of just one sentence. They seem to be putting an additional explanation layer over the language that is at least as voluminous as the language itself. Since I am temporarily doing only very little professional JavaScript programming, I have to keep learning efficiency high and cannot waste too much time on it. And since I have never had any difficulty with using "this" in JavaScript, except in this artificial example, I will stand back and will remain ignorant for now. Hans-Georg
[toc] | [prev] | [next] | [standalone]
| From | Christoph Michael Becker <cmbecker69@arcor.de> |
|---|---|
| Date | 2014-01-29 17:34 +0100 |
| Message-ID | <52e92d82$0$6663$9b4e6d93@newsspool2.arcor-online.net> |
| In reply to | #22868 |
Hans-Georg Michna wrote: > On Tue, 28 Jan 2014 19:00:28 +0100, Christoph Michael Becker > wrote: > >> Hans-Georg Michna wrote: > >>> Why is this.x in each of the inner functions not always >>> undefined, since it has never been defined inside those >>> functions? > >> That is explained in the section "Execution Contexts" of the ECMAScript >> specification[1]; keyword: ThisBinding. >> >> [1] <http://www.ecma-international.org/ecma-262/5.1/#sec-10.3> > > Thanks! Sorry, but that text is unintelligible to me, because it > explains everything in lots of terms that are all unknown to me. > It seems I would have to read and memorize the entire document > before being able to make sense of just one sentence. They seem > to be putting an additional explanation layer over the language > that is at least as voluminous as the language itself. Indeed, understanding (parts of) the ECMAScript language specification requires a considerable amount of time. However, it is the normative reference, and as such preferable, at least when in doubt. Björn had linked[1] to a respective MDN article[2], but as Thomas has already pointed out, this is not correct (at least, because it ignores strict mode); with some caution, however, this article (as well as others on MDN) are helpful. > Since I am temporarily doing only very little professional > JavaScript programming, I have to keep learning efficiency high > and cannot waste too much time on it. And since I have never had > any difficulty with using "this" in JavaScript, except in this > artificial example, I will stand back and will remain ignorant > for now. While the example seems to be artificial, the "this" problem is very real for object oriented programming. There are well known workarounds, such as introducing a variable called that[3], but AFAIK a clean solution was only introduced in ECMAScript Ed. 5.1 with Function.prototype.bind()[4][5]. [1] <news:aovhe9deho4vo7pnd6gsv3van71moamck1@hive.bjoern.hoehrmann.de> [2] <https://developer.mozilla.org/en/docs/Web/API/window.setTimeout#The_.22this.22_problem> [3] <http://stackoverflow.com/questions/4886632/what-does-var-that-this-mean-in-javascript> [4] <http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4> [5] <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind> -- Christoph M. Becker
[toc] | [prev] | [next] | [standalone]
| From | Jim T. <x@y.z> |
|---|---|
| Date | 2014-01-29 12:45 -0500 |
| Message-ID | <e4fie91q2e6ugl5tjf74fnteit6slumc1c@4ax.com> |
| In reply to | #22876 |
On Wed, 29 Jan 2014 17:34:16 +0100, Christoph Michael Becker <cmbecker69@arcor.de> wrote: >Hans-Georg Michna wrote: > >> On Tue, 28 Jan 2014 19:00:28 +0100, Christoph Michael Becker >> wrote: >> >>> Hans-Georg Michna wrote: >> >>>> Why is this.x in each of the inner functions not always >>>> undefined, since it has never been defined inside those >>>> functions? >> >>> That is explained in the section "Execution Contexts" of the ECMAScript >>> specification[1]; keyword: ThisBinding. >>> >>> [1] <http://www.ecma-international.org/ecma-262/5.1/#sec-10.3> >> >> Thanks! Sorry, but that text is unintelligible to me, because it >> explains everything in lots of terms that are all unknown to me. >> It seems I would have to read and memorize the entire document >> before being able to make sense of just one sentence. They seem >> to be putting an additional explanation layer over the language >> that is at least as voluminous as the language itself. > >Indeed, understanding (parts of) the ECMAScript language specification >requires a considerable amount of time. However, it is the normative >reference, and as such preferable, at least when in doubt. Björn had >linked[1] to a respective MDN article[2], but as Thomas has already >pointed out, this is not correct (at least, because it ignores strict >mode); with some caution, however, this article (as well as others on >MDN) are helpful. > >> Since I am temporarily doing only very little professional >> JavaScript programming, I have to keep learning efficiency high >> and cannot waste too much time on it. And since I have never had >> any difficulty with using "this" in JavaScript, except in this >> artificial example, I will stand back and will remain ignorant >> for now. > >While the example seems to be artificial, the "this" problem is very >real for object oriented programming. There are well known workarounds, >such as introducing a variable called that[3], but AFAIK a clean >solution was only introduced in ECMAScript Ed. 5.1 with >Function.prototype.bind()[4][5]. Probably the most common line in my code is 'var t = this'. > >[1] <news:aovhe9deho4vo7pnd6gsv3van71moamck1@hive.bjoern.hoehrmann.de> >[2] ><https://developer.mozilla.org/en/docs/Web/API/window.setTimeout#The_.22this.22_problem> > >[3] ><http://stackoverflow.com/questions/4886632/what-does-var-that-this-mean-in-javascript> >[4] <http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4> >[5] ><https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind>
[toc] | [prev] | [next] | [standalone]
| From | Hans-Georg Michna <hans-georgNoEmailPlease@michna.com> |
|---|---|
| Date | 2014-01-30 09:09 +0100 |
| Message-ID | <r42ke957t537fqh3mfh1alc30leavp8o6u@4ax.com> |
| In reply to | #22876 |
Thanks for the very good hints, everyone! I'll do my best to make use of them. Hans-Georg
[toc] | [prev] | [next] | [standalone]
| From | Alon Melanker <melankeril@gmail.com> |
|---|---|
| Date | 2014-01-29 01:52 -0800 |
| Message-ID | <4db39251-6142-4a8d-a6f4-027a93fef383@googlegroups.com> |
| In reply to | #22841 |
On Tuesday, January 28, 2014 4:58:34 PM UTC+2, Thomas 'PointedEars' Lahn wrote:
> Alon Melanker wrote:
>
>
>
> > function damn() {
>
> > this.x = 4;
>
> > var y = 3;
>
> >
>
> > setTimeout(function() {alert(this.x); alert(y)}, 100);
>
> >
>
> > this.aa = function() {
>
> > alert(this.x);
>
> > };
>
> > }
>
> >
>
> > aaa = new damn();
>
> > aaa.aa();
>
> >
>
> > What would be the output?!
>
> >
>
> > The correct answer should be 4 undefined and 3.
>
>
>
> Yes, although there is a race condition and it could be "undefined", "3",
>
> and "4" as well. Or a SyntaxError or TypeError exception could be thrown.
>
>
>
> > I answered 4 4 3.
>
> >
>
> > The question is why this.x inside setTimeout does not alert 4?
>
>
>
> I could tell you (and probably others will, with wrong explanations
>
> in-between), but try debugging first. You will learn more for your next
>
> interview this way.
>
>
>
> <http://devtoolsecrets.com/>
>
> <http://PointedEars.de/faq#posting>
>
>
>
> --
>
> PointedEars
>
>
>
> Twitter: @PointedEars2
>
> Please do not Cc: me. / Bitte keine Kopien per E-Mail.
Thanks, this help me understand that the problem, apparently when this function() {alert(this.x+'a'); alert(y+'b')} is invoked it is not invoked as an object method which leads that this refers to window object.
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-01-29 12:59 +0100 |
| Subject | setTimeout() (was: I thought I understood JavaScript till they asked me this on a job interview) |
| Message-ID | <5802771.9clCDhIZfi@PointedEars.de> |
| In reply to | #22869 |
Alon Melanker wrote:
[Fixed quotation]
> Thomas 'PointedEars' Lahn wrote:
>> Alon Melanker wrote:
>> > function damn() {
>> > this.x = 4;
>> > var y = 3;
>> >
>> > setTimeout(function() {alert(this.x); alert(y)}, 100);
>> >
>> > this.aa = function() {
>> > alert(this.x);
>> > };
>> > }
>> >
>> > aaa = new damn();
>> > aaa.aa();
>> >
>> > What would be the output?!
>> >
>> > The correct answer should be 4 undefined and 3.
>> > […]
>> > The question is why this.x inside setTimeout does not alert 4?
>>
>> I could tell you (and probably others will, with wrong explanations
>> in-between), but try debugging first. You will learn more for your next
>> interview this way.
>>
>> <http://devtoolsecrets.com/>
>> <http://PointedEars.de/faq#posting>
>> […]
>
> Thanks, this help me understand that the problem, apparently when this
> function() {alert(this.x+'a'); alert(y+'b')} is invoked it is not invoked
> as an object method which leads that this refers to window object.
Almost :) It depends on the (DOM) implementation, and you should not rely
on that “this” refers to a Window instance.
If the function is not called as a method, then the “this” value is set to
the Global Object in non-strict mode, and to “undefined” in strict mode,
when control enters the function execution context.
If the function is called as a method of the object referred to by the
“window” property of the Global Object, or a Window instance, the “this”
value is set to a reference to it.
It is not easy to tell the two objects apart because they are either
inheriting from each other or are part of the same scope chain. (Therefore,
some people have the misconception that they are the same object.) However,
using ECMAScript Edition 5.x strict mode, i.e. in a more recent browser, you
can do it with the following code:
/* window.alert() instead of console.log() should also work */
setTimeout(function () { "use strict"; console.log(this); }, 100);
The difference is this: In strict mode, if the function is not called as a
method, the “this” value is set to “undefined”. If instead it is called as
a method, the “this” value is set to the object it is called as a method of.
[1]
My results show that in Chromium 31 for GNU/Linux the function is called as
a method of a Window instance. This is unsurprising because setTimeout()
really is a method of Window instances, not of the Global Object (it is a
*host* object’s method, not a native one’s; it is _not_ part of the
programming language, but of the capabilities of the host environment), and
thus should be written
window.setTimeout(…);
Likewise for alert(…).
The other two possibilities I mentioned are that a SyntaxError or TypeError
exception could be thrown. There is a third possibility, a ReferenceError
exception.
A SyntaxError exception will be thrown (or something to the same effect will
happen) if anonymous function expressions are not supported. This is
possible, but increasingly unlikely these days. Anonymous function
expressions were introduced with
- Netscape JavaScript 1.2 in Navigator 4.04¹;
- Microsoft JScript 5.5.6330 in Internet Explorer 5.5 or earlier;
- Opera ECMAScript 7.02 in Opera 7.02 or earlier;
- KDE JavaScript 4.6.5 or earlier;
- Apple JavaScriptCore 531.22.7 in Safari 4.05 or earlier, and
- Google V8 3.7.12.12 in Chrome 17.0.963.78 and earlier.
A TypeError exception will be thrown if “setTimeout” or “alert” do not refer
to a callable object. This can likely be prevented if a feature test
determines that their values are likely callable before they are called.
A ReferenceError exception will be thrown if setTimeout() or alert() are not
properties of an object in the scope chain. That is, either there are no
such methods (unsuitable host environment), or the object that they are
methods of is not in the scope chain of the execution context of the
/CallExpression/s. This also shows that it is safer to use
window.setTimeout() and window.alert(), respectively.
See jsx.object.isHostMethod() [3] for a solution regarding the latter two
possibilities.
Please trim your quotations to the relevant parts next time, as explained in
the FAQ referred above. And avoid Google Groups; among other bugs, it has
inserted interleaving empty lines in your posting.
___________
¹ The ECMAScript Support Matrix 2 [2] is saying “JavaScript 1.5” because
the testing framework is not yet compatible with JavaScript versions
before 1.5.
[1] ECMAScript Language Specification, Edition 5.1, sections 11.2.3,
13.2.1, and 10.4.3.
<http://ecma-international.org/ecma-262/5.1/#sec-11.2.3>
<http://ecma-international.org/ecma-262/5.1/#sec-13.2.1>
<http://ecma-international.org/ecma-262/5.1/#sec-10.4.3>
[2] <http://PointedEars.de/es-matrix>
[3] <http://PointedEars.de/wsvn/JSX/branches/live/object.js>
<http://PointedEars.de/wsvn/JSX/trunk/object.js>
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Bjoern Hoehrmann <bjoern@hoehrmann.de> |
|---|---|
| Date | 2014-01-29 14:30 +0100 |
| Message-ID | <aovhe9deho4vo7pnd6gsv3van71moamck1@hive.bjoern.hoehrmann.de> |
| In reply to | #22840 |
* Alon Melanker wrote in comp.lang.javascript:
> function damn() {
> this.x = 4;
> var y = 3;
>
> setTimeout(function() {alert(this.x); alert(y)}, 100);
>
> this.aa = function() {
> alert(this.x);
> };
> }
>
> aaa = new damn();
> aaa.aa();
>
>What would be the output?!
That depends on how `setTimeout` invokes the function object passed to
it. Consider as another example
(function(){ console.log(this) }).call(1)
(function(){ console.log(this) }).call("")
The first line will log a Number, the second will log a String because
`this` is bound to the value passed to the `call` method. So you need to
consult documentation for the `setTimeout` function, say
https://developer.mozilla.org/en/docs/Web/API/window.setTimeout#The_.22this.22_problem
which says
Code executed by setTimeout() is run in a separate execution context
to the function from which it was called. As a consequence, the this
keyword for the called function will be set to the window (or global)
object; it will not be the same as the this value for the function
that called setTimeout.
So the correct answer is, for the problem case, "same as the value of
the `x` property on the global object". If the code did something along
the lines of
window.x = "123";
then it would alert `123` instead of `undefined`.
--
Björn Höhrmann · mailto:bjoern@hoehrmann.de · http://bjoern.hoehrmann.de
Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-01-29 15:39 +0100 |
| Message-ID | <2254161.6ScPoEuqDY@PointedEars.de> |
| In reply to | #22871 |
Bjoern Hoehrmann wrote: > So you need to consult documentation for the `setTimeout` function, say > > https://developer.mozilla.org/en/docs/Web/API/window.setTimeout#The_.22this.22_problem > > which says > > Code executed by setTimeout() is run in a separate execution context > to the function from which it was called. As a consequence, the this > keyword for the called function will be set to the window (or global) > object; it will not be the same as the this value for the function > that called setTimeout. You should not blindly believe everything you read. > So the correct answer is, for the problem case, "same as the value of > the `x` property on the global object". No, it is not. The correct answer is “depends”, as I have explained already. -- PointedEars Twitter: @PointedEars2 Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web