Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #17175
| Message-ID | <13959659.DiaCrlo6tG@PointedEars.de> (permalink) |
|---|---|
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
| Organization | PointedEars Software (PES) |
| Date | 2012-11-11 20:34 +0100 |
| Subject | Re: eval - how to |
| Newsgroups | comp.lang.javascript |
| References | <k7iqg9$n49$1@speranza.aioe.org> <ad4ffcf9-f94f-44c4-b425-7310b78e92bb@m13g2000vbd.googlegroups.com> <k7jsi7$h6a$1@speranza.aioe.org> <2836184.TlQAl5i4AK@PointedEars.de> <k7mocc$sec$1@speranza.aioe.org> |
| Followup-To | comp.lang.javascript |
Followups directed to: comp.lang.javascript
Cezary Tomczyk wrote:
> W dniu 2012-11-10 11:15, Thomas 'PointedEars' Lahn pisze:
>> [73 lines]
>
> Good way to present hot it works. Many times just a diagram is better
> than 1000 words.
And often less is more.
>> In non-strict code, the error occurs where the `?' is. In strict code,
>> the error occurs earlier, where the second `a' is attempted to be
>> assigned to. For strict mode essentially forbids augmenting the Global
>> Object (or any other object in the scope chain outside the local
>> execution context) by simple assignment to an identifier in function or
>> eval code.
>
> Hmm, something weird.
>
> "Note: Functions created with the Function constructor do not create
> closures to their creation contexts; they always run in the window
> context (unless the function body starts with a "use strict"; statement,
> in which case the context is undefined)."
>
> Source:
> https://developer.mozilla.org/en-
US/docs/JavaScript/Reference/Global_Objects/Function
>
> "context is undefined"?
AISB: Read the Specification first, only then the vendor documentation. For
the vendor is an implementor of the Specification, and might have gotten the
Specification wrong. It has happened before.
And keep in mind that MDN is a wiki. Anyone (particularly non-Mozilla
people) can write any nonsense there (but not for long, hopefully). I know,
for I had to correct some parts of MDN, or rather MDC (Mozilla Developer
Center) as it was called at the time.
What they perhaps meant to say is that the [[Scope]] property of Function
instances created with the Function constructor contains only the Global
Object, as it is specified in the ECMAScript Language Specification, 5.1
Edition, section 15.3.3.
> If I run in console Firefox 16.0.2:
>
> var t = 50;
>
> (function () {
> var a = 10;
> Function('"use strict"; console.log(t); a = 20;')();
> })();
>
> then results of console is "50". As I understand Function is run in
> window context because t is "50" instead of "undefined".
No, function code created this way is always executed "in window context"
because the [[Scope]] property of the associated Function instance contains
only the Global Object (or the Global Environment).
> Even more confuses.
Understandable, given that you are trying to comprehend a misleading, if not
patently wrong explanation.
> Example:
>
> var t = 50;
>
> (function () {
> var a = 10;
> Function('"use strict"; console.log(a); a = 20;')();
> })();
>
> shows me in console result "20". I expected "a" with "10". I thought
> that scope chain is just inside Function and no more.
No, per Specification the scope chain of such code contains the local
Variable Object (or Local Environment) and the Global Object (or Global
Environment):
| 15.3.1 The Function Constructor Called as a Function
|
| When Function is called as a function rather than as a constructor, it
| creates and initialises a new Function object. Thus the function call
| Function(...) is equivalent to the object creation expression new
| Function(...) with the same arguments.
|
| […]
| 15.3.2 The Function Constructor
|
| When Function is called as part of a new expression, it is a constructor:
| it initialises the newly created object.
|
| 15.3.2.1 new Function (p1, p2, ... , pn, body)
|
| […]
| 9. If body is strict mode code (see 10.1.1) then let strict be true, else
| let strict be false.
| 10. If strict is true, throw any exceptions specified in 13.1 that apply.
| 11. Return a new Function object created as specified in 13.2 passing P as
| the FormalParameterListopt and body as the FunctionBody. Pass in the
| Global Environment as the Scope parameter and strict as the Strict
| flag.
| 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:
|
| […]
| 9. Set the [[Scope]] internal property of F to the value of Scope.
| […]
| 19. If Strict is true, then
| a. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
| b. Call the [[DefineOwnProperty]] internal method of F with arguments
| "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower,
| [[Enumerable]]: false, [[Configurable]]: false}, and false.
| c. Call the [[DefineOwnProperty]] internal method of F with arguments
| "arguments", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower,
| [[Enumerable]]: false, [[Configurable]]: false}, and false.
No other provisions are made for strict mode there, but strict mode does not
matter here. You will notice that the [[Scope]] property is used when the
function is called, to create a new lexical environment (section 10.4.3)
that is used in identifier resolution as specified in section 10.3.1.
Therefore, a ReferenceError exception should have been thrown on
`console.log(a);' in any case because `a' was neither declared in the
(inner) function code nor was it an existing property on the Global Object
(it is thrown in Chromium "22.0.1229.94 Built on Debian wheezy/sid, running
on Debian 6.0.6 (161065)"). The assignment to `a', which should have thrown
another ReferenceError because of strict mode, should not have been reached
at all.
So you have probably observed an implementation bug here. This would be
unsurprising in a beta version such as Firefox 16.0.3 (apparently version
16.0.2 is the currently stable version). That said, the `Function'
constructor has a long history of being erroneously implemented, and it
should probably be avoided because of that.
I am getting (correctly) a ReferenceError with message "a is not defined"
both with and without Firebug 1.9.2 in Iceweasel 10.0.10. The behavior in
Firefox 16.0.3 may be a SpiderMonkey regression. But one wonders if this
has happened because you have assigned to a global `a' property before
running this code instead.
>>> Then I've got from console "ReferenceError: s is not defined" which is
>>> expected by me.
>>
>> Exactly, but your logic is flawed.
>
> Perhaps,
No, that much is certain. If you assign in function code to an identifier
that was not declared in that code, there are three possible outcomes:
1. You are assigning to a property of the next object in the scope chain
that has a property of that name.
2. If the function code is not strict code, you are augmenting the Global
Object with a new enumerable, deletable, writable property.
3. If the function code is strict code, a ReferenceError exception is
thrown.
So, as I said often before here and elsewhere, you should declare your
identifiers.
PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on a Web
page appears to be yearning for the bad old days, before the Web, when you
had very little chance of reading a document written on another computer,
another word processor, or another network. -- Tim Berners-Lee
Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-09 12:47 +0100
Re: eval - how to Asen Bozhilov <asen.bozhilov@gmail.com> - 2012-11-09 05:53 -0800
Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-09 22:28 +0100
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 10:23 +0100
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 11:15 +0100
Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-11 00:35 +0100
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-11 20:34 +0100
Re: eval - how to Dr J R Stockton <reply1245@merlyn.demon.co.uk.invalid> - 2012-11-10 22:42 +0000
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-09 17:46 +0100
Re: eval - how to Tim Streater <timstreater@greenbee.net> - 2012-11-09 17:00 +0000
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-09 18:19 +0100
Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-09 22:49 +0100
Re: eval - how to Asen Bozhilov <asen.bozhilov@gmail.com> - 2012-11-09 16:40 -0800
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 11:36 +0100
Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-10 13:29 +0100
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 13:55 +0100
Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-10 14:17 +0100
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 20:50 +0100
Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-10 22:54 +0100
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-11 15:22 +0100
Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-11 16:24 +0100
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-11 19:23 +0100
Re: eval - how to Asen Bozhilov <asen.bozhilov@gmail.com> - 2012-11-11 10:40 -0800
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-11 20:41 +0100
Re: eval - how to Asen Bozhilov <asen.bozhilov@gmail.com> - 2012-11-11 13:34 -0800
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-11 23:03 +0100
Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 10:21 +0100
Re: eval - how to SAM <stephanemoriaux.NoAdmin@wanadoo.fr.invalid> - 2012-11-10 04:16 +0100
csiph-web