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


Groups > comp.lang.javascript > #32025

Re: What I learned today

From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Newsgroups comp.lang.javascript
Subject Re: What I learned today
Date 2016-12-29 19:48 +0100
Organization PointedEars Software (PES)
Message-ID <7272888.NyiUUSuA9g@PointedEars.de> (permalink)
References <JavaScript-20161229003655@ram.dialup.fu-berlin.de> <assignment-and-references-in-ECMAScript-20161229185228@ram.dialup.fu-berlin.de>

Show all headers | View raw


Stefan Ram wrote:

> ram@zedat.fu-berlin.de (Stefan Ram) writes:
>>- The "references" are in ECMAscript to describe what is
>>happening when functions return values that can be
>>assigned to ("references"), but this only is intended
>>for host objects. Otherwise, JavaScript can be described
>>with the concept of bindings (to names) alone.
> 
>   The Assignement In ECMAScript
>   (based loosely on ECMA-262 as of June 2016)

That is, <http://www.ecma-international.org/ecma-262/7.0/>.
 
>   Here, I will now give a /simplified/ description of
>   what

… *you* think …

>   is happening in ECMAScript when one fires up his
>   browser and enters
> 
> a = 2
> 
>   into the JavaScript console.
> 
> […]
>   8.3.2 »ResolveBinding( name )«
> 
>   (This is still about getting the reference to the left side.)
> 
>   »ResolveBinding« essentially calls »GetIdentifierReference( glob,
>   name )«. »glob« in this case is the global lexical environment,
>   which has been initialized at the start of script execution
>   according to 15.1.10, step 1 and 7 to be the global environment.
> 
>   8.2.1. »GetIdentifierReference( glob, name )«
> 
>   (This is still about getting the reference to the left side.)
> 
>   »GetIdentifierReference( glob, name )« essentially returns the
>   reference »[ glob, name ]« (according to step 4.a).
> 
>   12.15.4 »=« The Assignment
> 
>   Now, that we have gotten the reference »[ glob, name ]« to
>   the left side, the assignment essentially calls
>   »PutValue( [ glob, name ], newValue )«.
> 
>   6.2.3.2 »PutValue( [ glob, name ], newValue )«
> 
>   This value put operation essentially calls
>   »glob.[[Set]]( [ glob, name ], newValue, glob )«.

You have omitted important aspects.

| 6.2.3.2 PutValue (V, W)
| 
| […]
|   3. If Type(V) is not Reference, throw a ReferenceError exception.
|   4. Let base be GetBase(V).
|   5. If IsUnresolvableReference(V) is true, then
|        a. If IsStrictReference(V) is true, then
|             Throw a ReferenceError exception.

This means that if you have declared strict mode and there is no object in 
the scope chain that has a property whose name corresponds with the 
identifier, and there is also no variable who does, a ReferenceError 
exception is thrown.

|        b. Let globalObj be GetGlobalObject().
|        c. Return ? Set(globalObj, GetReferencedName(V), W, false).

[sic]

This means that if you have not declared strict mode, and there is no such 
property name or variable identifier, the global object will be augmented 
with a property that has the identifier as its name.

|   6. Else if IsPropertyReference(V) is true, then

But if the identifier can be resolved instead, …

|      a. If HasPrimitiveBase(V) is true, then

and the base value is a primitive value, …

|            i. Assert: In this case, base will never be null or undefined.
|           ii. Set base to ToObject(base).$

… then convert that value to an object …

|      b. Let succeeded be
|         ? base.[[Set]](GetReferencedName(V), W, GetThisValue(V)).

… for the purpose of property write access.

|      c. If succeeded is false and IsStrictReference(V) is true, throw a 
|      TypeError exception.

If the property could not be written to, throw an exception.

|      d. Return.

Otherwise return successfully.  (AISB.  This is why it is error-prone to use 
identifiers without declaration as if they were variables.)
 
>   9.1.9 »glob.[[Set]]( [ glob, name ], newValue, glob )«

You have misquoted the specification and added your own misconceptions.

The actual text is

| 9.1.9 [[Set]] ( P, V, Receiver)

indicating that it is not necessarily the global object whose property is 
being written to here.

Also, there is not only one internal [[Set]] method; it depends on the 
object who has the property which [[Set]] method is invoked, and it depends 
on the property.  For example:

| Table 3: Attributes of an Accessor Property
| 
| Attribute Name  Value Domain        Description
| […]
| [[Set]]         Object | Undefined  If the value is an Object it must be a 
|                                     function object. The function's
|                                     [[Call]] internal method (Table 6) is
|                                     called with an arguments list
|                                     containing the assigned value as its
|                                     sole argument each time a set access
|                                     of the property is performed. The
|                                     effect of a property's [[Set]]
|                                     internal method may, but is not
|                                     required to, have an effect on the
|                                     value returned by subsequent calls to
|                                     the property's [[Get]] internal
|                                     method.

>   This non-static method essentially calls the static
>   helper method 9.1.9.1
>   »OrdinarySet( glob, [ glob, name ], newValue, glob )«.
> 
> […]

Ex falso quodlibet.

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

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


Thread

Re: What I learned today Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-12-29 19:48 +0100

csiph-web