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


Groups > comp.lang.javascript > #26505

Re: Can somebody explain this to me

From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Newsgroups comp.lang.javascript
Subject Re: Can somebody explain this to me
Date 2015-01-08 22:09 +0100
Organization PointedEars Software (PES)
Message-ID <3039223.p41ss7ciAv@PointedEars.de> (permalink)
References (7 earlier) <1676759.bbBSSFFLiy@PointedEars.de> <66nsaal9kcls42elbn16dkbv3fiille47o@4ax.com> <m8ltkq$rq3$1@solani.org> <3105476.iMYZV00USQ@PointedEars.de> <m8mjd3$de4$1@solani.org>

Show all headers | View raw


Christoph M. Becker wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Christoph M. Becker wrote:
>>> A function declaration creates a function object that is passed in the
>>> *variable* environment of the running execution context as environment;
>>> a function object that is created by a function expression is passed in
>>> the *lexical* environment.
>> 
>> Objects are not "passed in environments".
> 
> I had written (simplified): "an object that is passed in something as
> environment".  The "in" is superfluous or plain wrong -- I'm not sure.

If you consult the ECMAScript Language Specification again, you can see that 
this statement is wrong either way:

,-<http://ecma-international.org/ecma-262/5.1/#sec-10.2>
| 
| A Lexical Environment is a specification type used to define the 
| association of /Identifiers/ to specific variables and functions based 
| upon the lexical nesting structure of ECMAScript code.

IOW, Lexical Environments are used for resolving identifiers instead (this 
is not an ECMAScript-specific idea).  Neither are objects "passed in 
something as environment" nor are objects passed in(to) environments; 
certainly Function instances (your “function objects”) are not.

As for function declarations vs. expressions:

<http://ecma-international.org/ecma-262/5.1/#sec-11.2.5>

| Semantics
| 
| The production
| 
| FunctionDeclaration : function Identifier ( FormalParameterList_opt ) { 
| FunctionBody }
| 
| is instantiated as follows during Declaration Binding instantiation 
| (10.5):
| 
| 1. Return the result of creating a new Function object as specified in 
|    [section] 13.2 with parameters specified by FormalParameterList_opt, 
|    and body specified by FunctionBody.
|    Pass in the VariableEnvironment of the running execution context as
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|    the Scope. Pass in true as the Strict flag if the FunctionDeclaration
     ^^^^^^^^^
|    is contained in strict code or if its FunctionBody is strict code.
| 
| 
| The production
| 
| FunctionExpression : function ( FormalParameterList_opt ) { FunctionBody }
| 
| is evaluated as follows:
| 
| 1. Return the result of creating a new Function object as specified in 
|    [section] 13.2 [“Creating Function Objects”; the ed.] with parameters 
|    specified by FormalParameterList_opt and body specified by 
|    FunctionBody.
|    Pass in the LexicalEnvironment of the running execution context
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|    as the Scope.
     ^^^^^^^^^^^^^
|    Pass in true as the Strict flag if the FunctionExpression is contained
|    in strict code or if its FunctionBody is strict code.

The section referred is

<http://ecma-international.org/ecma-262/5.1/#sec-13.2>

| 13.2 Creating Function Objects
| 
| Given an optional parameter list specified by FormalParameterList, a body 
| specified by FunctionBody, a Lexical Environment specified by Scope, and a 
| Boolean flag Strict, a Function object is constructed as follows:
| 
| 1. Create a new native ECMAScript object and let F be that object.
| […]
| 9. Set the [[Scope]] internal property of F to the value of Scope.
| […]

Continuing in section 11.2.5, you can read:

| The production
| 
| FunctionExpression : function Identifier ( FormalParameterListopt ) { 
| FunctionBody }
| 
| is evaluated as follows:
| 
| 1. Let funcEnv be the result of calling NewDeclarativeEnvironment passing 
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|    the running execution context’s Lexical Environment as the argument
                                                         ^^^^^^^^^^^^^^^
The section referred is

<http://ecma-international.org/ecma-262/5.1/#sec-10.2.2.2>

| 10.2.2.2 NewDeclarativeEnvironment (E)
| 
| When the abstract operation NewDeclarativeEnvironment is called with 
| either a Lexical Environment or null as argument E the following steps are 
| performed:
| 
| 1. Let env be a new Lexical Environment.
| 2. Let envRec be a new declarative environment record containing no 
|    bindings.
| 3. Set env’s environment record to be envRec.
| 4. Set the outer lexical environment reference of env to E.
| 5. Return env.

The text above shows that I have been partially wrong: The “scope rules”, as 
you put it, *do* differ between function declarations and function 
expressions; they also differ between function expressions with and without 
identifier.  The subtype, so to speak, of the Function instance’s [[Scope]] 
property’s value is different in both cases, indeed (its type is *always* 
Lexical Environment because by definition both LexicalEnvironment and 
VariableEnvironment are Lexical Environments).

This can be explained as follows:

The identifier of a function created by function declaration needs to be 
available both from inside the function and the (outer) execution context in 
which it was declared.  A Function instance created from a function 
declaration can be accessed and modified from the execution context in which 
it was declared; the function can also modify itself when it is called¹: you 
can assign a value to the identifier of the function to do that, but you 
cannot delete the function, by a “delete” operation on its identifier.  IOW, 
it is treated *like a variable* that is declared in the (outer) execution 
context in which the function was declared.  Also, from the inside 
identifiers in the outer execution context need to be accessible (closure):

  /* result should be "answer" per §12.2, but apparently only available 
     internally */
  var answer = 42;

  function foo (bar)
  {
    /* 1 */
    foo.length;
    
    /* false */
    delete foo;

    /* function foo (bar) { … } */
    foo;

    /* function () { … } */
    foo = function () { return answer; };
  }

  /* undefined */
  foo();

  /* 42 */
  foo();

  foo = function () { return 23; };
  
  /* 23 */
  foo();

[This also allows another function declaration with the same identifier to 
overwrite a previous one in the same execution context.¹]

A function created by function expression without identifier is anonymous; 
without explicit reference, it cannot be referred (or modified) from the 
inside or the outside², but from the inside identifiers in the outer 
execution context need to be accessible (closure):

  /* Script-kiddies, don't do this (at home) */
  var counter = 10;

  (function () {
    if (counter > 0)
    {
      arguments.callee(--counter);
    }
  }());

A function expression with identifier must be treated differently than both 
of those because it must be possible to refer to the resulting Function 
instance by identifier from within the function (for introspection and 
recursion), but not from its defining outer execution context.  Also, it 
must still work as a closure.

  /* see above */
  var answer = 42;

  /* function bar (…) { … } */
  var foo = function bar (baz) {
    /* 1 */
    bar.length;

    /* function () { … } */
    bar = function () { return answer; };
  };

  /* undefined */
  foo();

  /* undefined */
  foo();

  foo = function () { return 23; };
  
  /* overwrites/creates “bar” property, overwrites “bar” variable value,
     or throws “ReferenceError: bar is not defined” in strict mode */
  bar = function () { return 11; };

  /* 23 */
  foo();

______
¹ Loosely speaking.  What really happens is that the identifier then refers
  to a new Function instance, and the old instance is free to be garbage-
  collected unless it is still referred to by something else.  In the case
  of duplicate function declarations in an execution context, an optimizing
  compiler could skip the creation of all Function instances but the last
  one.
² Overwriting arguments.callee might effect that anyway, but that would
  not be conforming behavior (overwriting a property ought not change the
  object referred to by its value).

> Thanks for the clarifications. :)

You're welcome.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Can somebody explain this to me "Tony Johansson" <johansson.andersson@telia.com> - 2015-01-06 00:48 +0100
  Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-06 01:40 +0100
    Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-06 16:01 +0000
      Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-06 17:26 +0100
        Re: Can somebody explain this to me Joao Rodrigues <groups_jr-1@yahoo.com> - 2015-01-07 00:45 -0200
          Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-07 04:35 +0100
            Re: Can somebody explain this to me Joao Rodrigues <groups_jr-1@yahoo.com.br> - 2015-01-07 16:15 -0200
              Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-07 21:20 +0100
                Re: Can somebody explain this to me "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-01-08 00:00 +0100
                Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-08 00:09 +0100
                Re: Can somebody explain this to me "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-01-08 10:53 +0100
                Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-08 16:17 +0100
                Re: Can somebody explain this to me "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-01-08 17:04 +0100
                Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-08 19:02 +0100
        Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-07 15:37 +0000
          Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-07 17:01 +0100
            Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-08 10:43 +0000
              Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-08 13:16 +0100
          Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-08 16:43 +0100
            Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-09 20:16 +0000
              Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-09 22:11 +0100
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-10 16:58 +0000
                Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-11 12:41 +0100
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-12 15:46 +0000
                Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-12 18:01 +0100
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-13 10:38 +0000
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-14 16:06 +0000
              Re: Can somebody explain this to me Scott Sauyet <scott.sauyet@gmail.com> - 2015-01-21 13:00 -0800
                Re: Can somebody explain this to me Joao Rodrigues <groups_jr-1@yahoo.com> - 2015-01-21 20:53 -0200
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-22 11:43 +0000
                Re: Can somebody explain this to me Joao Rodrigues <groups_jr-1@yahoo.com.br> - 2015-01-22 10:20 -0200
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-23 19:42 +0000
                Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-28 18:14 +0100
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-22 11:39 +0000
                Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-22 13:27 +0100
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-23 14:36 +0000
                Re: Can somebody explain this to me Scott Sauyet <scott.sauyet@gmail.com> - 2015-01-23 08:51 -0800
                Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-23 23:17 +0100
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-24 16:42 +0000
                Re: Can somebody explain this to me Scott Sauyet <scott.sauyet@gmail.com> - 2015-01-24 15:35 -0800
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-25 11:08 +0000
                Re: Can somebody explain this to me "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2015-01-26 08:33 -0800
                Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-27 14:10 +0100
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-28 15:50 +0000
                Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-28 18:26 +0100
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-29 10:29 +0000
                Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-31 00:37 +0100
                Re: Can somebody explain this to me "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2015-01-28 13:30 -0800
                Re: Can somebody explain this to me "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-01-28 22:40 +0100
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-29 10:32 +0000
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-29 10:23 +0000
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-29 11:04 +0000
                Re: Can somebody explain this to me "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2015-01-26 08:21 -0800
                Re: Can somebody explain this to me Scott Sauyet <scott.sauyet@gmail.com> - 2015-01-26 11:10 -0800
                Re: Can somebody explain this to me Scott Sauyet <scott.sauyet@gmail.com> - 2015-01-22 06:36 -0800
      Re: Can somebody explain this to me Tim Streater <timstreater@greenbee.net> - 2015-01-06 17:34 +0000
        Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-06 19:03 +0100
          Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-07 15:07 +0000
            Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-07 16:41 +0100
              Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-07 17:22 +0100
                Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-08 10:36 +0000
                Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-08 13:36 +0100
                Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-08 17:54 +0100
                Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-08 19:48 +0100
                Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-08 22:09 +0100
                Re: Can somebody explain this to me Joao Rodrigues <groups_jr-1@yahoo.com.br> - 2015-01-08 18:22 -0200
                Re: Can somebody explain this to me "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-01-08 22:13 +0100
                Re: Can somebody explain this to me Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-08 22:25 +0100
              Re: Can somebody explain this to me John Harris <niam@jghnorth.org.uk.invalid> - 2015-01-08 10:25 +0000
                Re: Can somebody explain this to me "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-01-08 11:33 +0100

csiph-web