Path: csiph.com!usenet.pasdenom.info!news.albasani.net!weretis.net!feeder1.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: Can somebody explain this to me Date: Thu, 08 Jan 2015 17:54:25 +0100 Organization: PointedEars Software (PES) Lines: 106 Message-ID: <3105476.iMYZV00USQ@PointedEars.de> References: <1590597.KOVAYohEvS@PointedEars.de> <060120151734221023%timstreater@greenbee.net> <1676759.bbBSSFFLiy@PointedEars.de> <66nsaal9kcls42elbn16dkbv3fiille47o@4ax.com> Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: solani.org 1420736088 20846 eJwFwQkBwDAIA0BLfAmdHAbFv4TewansDIKBxbaspLHN1zTcUT57CnKBYJbmf3dOmMRcfngOJxCc (8 Jan 2015 16:54:48 GMT) X-Complaints-To: abuse@news.solani.org NNTP-Posting-Date: Thu, 8 Jan 2015 16:54:48 +0000 (UTC) User-Agent: KNode/4.14.2 X-User-ID: eJwNwokRwDAIA7CVYlK+cSjg/UdoT9JrsPbH1B7lbzOQMrLtQZ+D1EA5AZYK3piWvROs6M6xOrunyKWZID9YnRY1 Cancel-Lock: sha1:9fO8rqjTV2e2K/WOG8cnGQq7l5c= X-NNTP-Posting-Host: eJwFwYEBwCAIA7CXwFLAc1bF/09YQqTnqUhm8PGt7d4qzuyLe6atuKRjBukLB9wRDCmra/gDFNoQlA== Xref: csiph.com comp.lang.javascript:26500 Christoph M. Becker wrote: > John Harris wrote: >> On Wed, 07 Jan 2015 17:22:40 +0100, Thomas 'PointedEars' Lahn >> wrote: >>> It is because, as is obvious from the above, he has not realized yet >>> that there are (at least) two ways to “define” a function in ECMAScript, >>> of which one includes a *declaration*. >> >> Both ways create a function object. One way gives it a global name, >> the other need not. What else matters? > > Most importantly scope rules. The scope (chain) rules are the same with either syntax. > 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". | LexicalEnvironment | Identifies the Lexical Environment | | used to resolve identifier references made by code | | within this execution context. | --------------------+--------------------------------------------------- | VariableEnvironment | Identifies the Lexical Environment | | whose environment record holds bindings created by | | VariableStatements and FunctionDeclarations within | | this execution context. (intentional word-wrap) > Informally, one might say that function declarations are "hoisted". Yes, but as with all informal descriptions, it is imprecise and potentially misleading. For example, a so "hoisted" function can still access identifiers in the outer execution context even though they have only been defined (and assigned to) later, because it is a closure and because of the scope chain: var answer; function deepThought () { return answer; } /* undefined */ deepThought(); answer = 42; /* 42 */ deepThought(); > Another pitfall that one should be aware of is that the behavior of a > function expression in a statement context is standardized, while the > behavior of a function declaration (better called function statement > here) in a statement context is not, even though it is allowed in > several ECMAScript implementations. True. However, I think it is more important to realize that function expressions observe source code order (so I referred to that). A function defined with a function expression is not defined before execution *passed* the latter. /* 42 */ foo(); function foo () { return 42; } /* TypeError: undefined is not a function */ bar(); var bar = function () { return 42; }; [Per Specification, this is independent of whether the function *expression* contains an identifier (a function *declaration* must contain an identifier or it is parsed as a function expression). There is a JScript bug, fixed in version 9+ when in IE 9+ standards Document Mode¹ (test with Firebug Lite or F12 – developer tools), that allows the bar() call above to be successful if you write var bar = function bar () { return 42; }; instead. IOW, the function identifier can leak to the outer scope. ______ ¹ Did I already say that there is no javascript/Javascript?] -- PointedEars FAQ: | SVN: Twitter: @PointedEars2 | ES Matrix: Please do not cc me. / Bitte keine Kopien per E-Mail.