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


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

function(){}() and subsequent calls

Started byAndrew Poulos <ap_prog@hotmail.com>
First post2012-05-31 15:51 +1000
Last post2012-06-01 01:12 +0200
Articles 6 — 5 participants

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


Contents

  function(){}() and subsequent calls Andrew Poulos <ap_prog@hotmail.com> - 2012-05-31 15:51 +1000
    Re: function(){}() and subsequent calls Holger Suhr <holgerholgerde@yahoo.de> - 2012-05-31 08:51 +0200
      Re: function(){}() and subsequent calls Andrew Poulos <ap_prog@hotmail.com> - 2012-05-31 17:12 +1000
        Re: function(){}() and subsequent calls Gregor Kofler <usenet@gregorkofler.com> - 2012-05-31 13:40 +0200
        Re: function(){}() and subsequent calls Matt McDonald <matt@fortybelow.ca> - 2012-05-31 09:57 -0600
          Re: function(){}() and subsequent calls Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-06-01 01:12 +0200

#14250 — function(){}() and subsequent calls

FromAndrew Poulos <ap_prog@hotmail.com>
Date2012-05-31 15:51 +1000
Subjectfunction(){}() and subsequent calls
Message-ID<z42dnVxvhJ19m1rSnZ2dnUVZ_vCdnZ2d@westnet.com.au>
With
   var foo = function() {}()
if I later call
   foo()
I get an error. Whereas using
   var foo = function() {}
lets me call
   foo()

Adding the succeeding parentheses calls the function but does it alter 
it as well?

Andrew Poulos

[toc] | [next] | [standalone]


#14251

FromHolger Suhr <holgerholgerde@yahoo.de>
Date2012-05-31 08:51 +0200
Message-ID<jq74ed$s3p$1@news01.versatel.de>
In reply to#14250
Am 31.05.2012 07:51, schrieb Andrew Poulos:
> With
> var foo = function() {}()
> if I later call
> foo()
> I get an error. Whereas using
> var foo = function() {}
> lets me call
> foo()
>
> Adding the succeeding parentheses calls the function but does it alter
> it as well?
>
> Andrew Poulos

var foo = function(){}();

executes the no-name function and assingns the return value to foo.
typeof foo == "undefined"

var foo = function(){return true;}();
typeof foo == "boolean"

var foo = function(){};
assigns the function to foo
typeof foo == "function"

var foo = function(){return true;};
typeof foo == "function"

Holger

[toc] | [prev] | [next] | [standalone]


#14252

FromAndrew Poulos <ap_prog@hotmail.com>
Date2012-05-31 17:12 +1000
Message-ID<fcidnaenHatRhFrSnZ2dnUVZ_qCdnZ2d@westnet.com.au>
In reply to#14251
On 31/05/2012 4:51 PM, Holger Suhr wrote:
> Am 31.05.2012 07:51, schrieb Andrew Poulos:
>> With
>> var foo = function() {}()
>> if I later call
>> foo()
>> I get an error. Whereas using
>> var foo = function() {}
>> lets me call
>> foo()
>>
>> Adding the succeeding parentheses calls the function but does it alter
>> it as well?
>>
>> Andrew Poulos
>
> var foo = function(){}();
>
> executes the no-name function and assingns the return value to foo.
> typeof foo == "undefined"
>
> var foo = function(){return true;}();
> typeof foo == "boolean"
>
> var foo = function(){};
> assigns the function to foo
> typeof foo == "function"
>
> var foo = function(){return true;};
> typeof foo == "function"

Ah, so if I want it called immediately and still be available for 
subsequent calls I tried this
   var foo;
   (foo = function(){})();
which "works" but JSLint says "Bad invocation".

BTW I notice that <http://www.jslint.com/> has a nice new UI.

Andrew Poulos

[toc] | [prev] | [next] | [standalone]


#14253

FromGregor Kofler <usenet@gregorkofler.com>
Date2012-05-31 13:40 +0200
Message-ID<jq7lcb$354$1@dont-email.me>
In reply to#14252
Am 2012-05-31 09:12, Andrew Poulos meinte:

> Ah, so if I want it called immediately and still be available for
> subsequent calls I tried this
> var foo;
> (foo = function(){})();
> which "works" but JSLint says "Bad invocation".

While it works, it is hard to follow. Whats wrong with

var foo = function() {...};
foo();

*Much* easier to understand (particularly with a "real" function body), 
and just as efficient.

Gregor


-- 
http://vxweb.net

[toc] | [prev] | [next] | [standalone]


#14259

FromMatt McDonald <matt@fortybelow.ca>
Date2012-05-31 09:57 -0600
Message-ID<jq84e2$u92$1@dont-email.me>
In reply to#14252
On 12-05-31 01:12 AM, Andrew Poulos wrote:
> Ah, so if I want it called immediately and still be available for
> subsequent calls I tried this
> var foo;
> (foo = function(){})();
> which "works" but JSLint says "Bad invocation".

JSLint (and by proxy, Crockford) desires the right
parenthetical of an immediately invoked function expression
to follow the invocation. An example follows.

`var foo = (function () {}());`

will pass JSLint (`"use strict";` dogma aside).

> BTW I notice that <http://www.jslint.com/> has a nice new UI.

I disagree. I find it hideous.

-- 
Matt McDonald: Web/Flash Developer; Edmonton, Alberta, Canada

[toc] | [prev] | [next] | [standalone]


#14262

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-06-01 01:12 +0200
Message-ID<1970702.99vfnYFUyE@PointedEars.de>
In reply to#14259
Matt McDonald wrote:

> On 12-05-31 01:12 AM, Andrew Poulos wrote:
>> Ah, so if I want it called immediately and still be available for
>> subsequent calls I tried this
>> var foo;
>> (foo = function(){})();
>> which "works" but JSLint says "Bad invocation".
> 
> JSLint (and by proxy, Crockford) desires the right
> parenthetical of an immediately invoked function expression
> to follow the invocation. An example follows.
> 
> `var foo = (function () {}());`
> 
> will pass JSLint (`"use strict";` dogma aside).

I, too, while I do not agree with several of Douglas Crockford's notions 
about these languages, recommend to use the latter form because it makes 
clear where the value assigned to the variable begins and where it ends.  
(Especially with source code editors that support highlighting of matching 
parentheses.  It is the *return value* of the function that is assigned, 
_not_ a reference to the function.)

However, I do not think that not using that form is the reason why the 
assignment above raises the "Bad invocation" error (or warning?) here.  
Instead, I assume it is because of the nature of the simple assignment 
operation in ECMAScript and its conforming implementations.

Many people – myself included, until a year or so ago – expect the result of 
an assignment operation to be the value that the property assigned to 
(variables are just special properties) has *after* the operation.  This 
view may be encouraged by using the grouping operator (the parentheses), 
where in math it means that the value of that expression must be calculated 
first, which also does apply to other uses of the grouping operator.  But in 
fact, somewhat counter-intuitively, the evaluation result of an assignment 
operation – and therefore the evaluation result of the grouping operator 
expression here – is the evaluation result of the *right-hand side* *before* 
assignment took place (ES1 to 5.1, section 11.13 [1]).

So what is called here is a Function instance that may end up not to be 
referred by the `foo' variable's value afterwards.  For example, assume that 
a property referred left-hand side has a setter that prevents it from 
changing value, or just changing value to a Function instance reference.  
Such has been possible before in conforming implementations for built-in 
properties (e.g. per ES3, §15.10.7.4), and in some implementations in a 
proprietary way for user-defined properties [2]; the possibility for the 
latter has been standardized in ECMAScript Edition 5, section 15.2.3, and 
possibly refined in the currently latest 5.1 Edition [3].

Yet, at first sight of this code you would expect `foo' to refer to that 
function from now on.  Therefore, this is potentially confusing code even 
for intermediates, and such code is just bad code.  I assume, although I 
cannot be sure, that this is the actual reason why JSLint rejects it.  It 
would be interesting to learn Douglas' rationale about it; unless he posts 
here again, that might be most easily found in "The Good Parts", which I 
have read only partially yet.


PointedEars
___________
[1] <http://ecma-international.org/ecma-262/5.1/#sec-11.13>
[2] 
<https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/DefineSetter>
[3] <http://ecma-international.org/ecma-262/5.1/#sec-15.2.3>
-- 
> If you get a bunch of authors […] that state the same "best practices"
> in any programming language, then you can bet who is wrong or right...
Not with javascript. Nonsense propagates like wildfire in this field.
  -- Richard Cornford, comp.lang.javascript, 2011-11-14

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web