Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #22840 > unrolled thread

I thought I understood JavaScript till they asked me this on a job interview

Started byAlon Melanker <melankeril@gmail.com>
First post2014-01-28 05:57 -0800
Last post2014-01-29 15:39 +0100
Articles 13 — 7 participants

Back to article view | Back to comp.lang.javascript


Contents

  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

#22840 — I thought I understood JavaScript till they asked me this on a job interview

FromAlon Melanker <melankeril@gmail.com>
Date2014-01-28 05:57 -0800
SubjectI 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]


#22841

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2014-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]


#22842

FromHans-Georg Michna <hans-georgNoEmailPlease@michna.com>
Date2014-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]


#22849

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2014-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]


#22850

FromChristoph Michael Becker <cmbecker69@arcor.de>
Date2014-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]


#22868

FromHans-Georg Michna <hans-georgNoEmailPlease@michna.com>
Date2014-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]


#22876

FromChristoph Michael Becker <cmbecker69@arcor.de>
Date2014-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]


#22877

FromJim T. <x@y.z>
Date2014-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]


#22880

FromHans-Georg Michna <hans-georgNoEmailPlease@michna.com>
Date2014-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]


#22869

FromAlon Melanker <melankeril@gmail.com>
Date2014-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]


#22870 — setTimeout() (was: I thought I understood JavaScript till they asked me this on a job interview)

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2014-01-29 12:59 +0100
SubjectsetTimeout() (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]


#22871

FromBjoern Hoehrmann <bjoern@hoehrmann.de>
Date2014-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]


#22872

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2014-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