From: Jorge on
On Jan 26, 12:43 pm, "Matthias Reuter" <frontendg...(a)web.de> wrote:
> Jorge wrote:
> > window *is* already -in any decent browser- an alias of the global
> > object(1):
>
> I was wondering about that passage in ECMA-262, Section 10.1.5:
>
> "[...] for example, in the HTML document object model the window property  
> of the global object is
> the global object itself."
>
> That matches what you're saying and contradicts what several others are  
> saying. The question is, is this normative to the DOM or descriptive (e.g..  
> for the time it was written)?

It may not be normative, it might be just another de-facto standard
(there are many more, as you know). Or is there any browser in which:
<script>deFacto= window === this;</script> isn't true ?
--
Jorge.
From: Scott Sauyet on
On Jan 25, 10:48 pm, Thomas 'PointedEars' Lahn <PointedE...(a)web.de>
wrote:
> Scott Sauyet wrote:
> > Thomas 'PointedEars' Lahn wrote:

>>> First of all, according to the MSDN Library the reviver function is
>>> "called for each member of the [deserialized] object in post-order"; one
>>> would need to make sure that it only operates on those "members" that
>>> hold person data.
>
>> Well, you'd have to return the original value for Strings, Numbers,
>> etc.  But there is a pattern [ ... ]:
>
>> | myData = JSON.parse(text, function (key, value) {
>> |     var type;
>> |     if (value && typeof value === 'object') {
>> |         type = value.type;
>> |         if (typeof type === 'string' &&
>> |                 typeof window[type] === 'function') {
>> |             return new (window[type])(value);
>> |         }
>> |     }
>> |     return value;
>> | });
>
>> You could use this by adding "type":
>
>>     var people = [{type: "Person", first: "Thomas", last: "Lahn"}];
>
> Possible.  However, we do not need any reference to the constructor then
> (irresponsibly by `window[type]' or responsibly by refToGlobal[type]), for
> we have the identifier of the constructor already.

Obviously we can write the reviver however we choose. Although I've
seen this pattern in several places (possibly all derived from
JSON.org) we could hard-code something like the (untested) following:

var reviver = function (key, value) {
var type;
if (value && typeof value === 'object') {
type = value.type;
if (type == 'Person')
return new Person(value);
} else if (type == 'Address') {
return new Address(value);
} // etc.
}
return value;
};


> In addition, this only works with constructors that are properties of the
> Global Object; if we lose the needless reference check, it can work with
> other constructors, too (applying eval() if necessary).


I'm not sure I understand. Would you be willing to elaborate?

>>> Second, `this' does not always refer to the passed object in the reviver
>>> function; in JavaScript 1.8.1, [ ... ]
>>
>> Okay, I didn't realize this, but I'm not sure it matters.  I hadn't
>> thought of using "this" inside the function.

(I should have explicitly said "inside the reviver function".)

> You suggested to pass a reference to the constructor to JSON.parse().
> In case you did not notice, the constructor uses `this' a lot.

But if the constructor is used with "new" should the external value of
"this" make any difference?

-- Scott
From: Thomas 'PointedEars' Lahn on
Matthias Reuter wrote:

> Jorge wrote:
>> window *is* already -in any decent browser- an alias of the global
>> object(1):
>
> I was wondering about that passage in ECMA-262, Section 10.1.5:
>
> "[...] for example, in the HTML document object model the window property
> of the global object is the global object itself."
>
> That matches what you're saying and contradicts what several others are
> saying. The question is, is this normative to the DOM or descriptive
> (e.g. for the time it was written)?

As Richard said. I would like to add an explanation as to why it is
"descriptive (and only an example)", hopefully for future reference:

As a rule of thumb, examples in specifications are *never* normative.

If you look closely, you can recognize the level of requirement in the part
that you have omitted (`[...]'):

| 15.1 The Global Object
|
| [...] Initially the global object has the following properties:
|
| [...]
| * Additional host defined properties. This may include a property whose
^^^
| value is the global object itself; [see quotation above]

That little word "may" is very important; so important, that in many other
specifications it is written in ALL-CAPS -- "MAY" -- so that it is not
overlooked in the prose. It means that there is the possibility of what is
described, but no requirement is made by the specification that it needs to
be made happen, and no recommendation is made to make it happen or to make
it not happen. IOW, it is completely neutral wording, by contrast to
"must/shall" (absolute requirement to be), "should" (recommendation in
favor), "should not" (recommendation against), "shall not/must not"
(absolute requirement not to be). See also RFC 2119, which defines these
terms common to many (if not all) technical specifications, and which is
therefore referred to by many specifications (for example, W3C
specifications). (Unfortunately, it is not referred to explicitly by the
Editions of the ECMAScript Language Specification; however, given general
use, and the way these words are used in the Specification, there can be no
doubt as to their meaning.)

Then you need to consider the scope of the Specification; no *programming
language* standard can provide a normative basis for the implementation of
a *host-defined (proprietary) feature* based on some *markup language*.

There is _not_ /the/ "HTML document model", but several ones. Even at the
time this wording was first used (1999/2000) there were at least three DOM
APIs: the NN4 DOM, the MSHTML DOM, and W3C DOM HTML Level 1; the first two
were not called "DOM" at the time (the prevalent term was "DHTML", cf. the
MSDN Library which still employs that term), and the latter one (obsolete
since 2003) did not specify the `window' property (nor do its successors to
date). As a rule of thumb, double-check all statements made by ECMA people
about HTML or the DOM, and by W3C Specifications about ECMAScript
implementations (for example, there are similar errors in examples in HTML
4.01).

Finally, a property can _not_ *be* an object; it can only _refer_ to one.
(Unfortunately, the Specification employs sloppy wording in several
normative places, while being rather unnecessarily pedantic in others
[especially in Edition 5]; a property can _not_ have an object for its
value, but only a reference to the object.)


On a personal note, Jorge has been told these and other basic things a
hundred times before already, but he would not listen (or try to
understand). The record shows he is likely only trolling; ignore him.


HTH

PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
From: Thomas 'PointedEars' Lahn on
Scott Sauyet wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>> > Thomas 'PointedEars' Lahn wrote:
>>>> First of all, according to the MSDN Library the reviver function is
>>>> "called for each member of the [deserialized] object in post-order";
>>>> one would need to make sure that it only operates on those "members"
>>>> that hold person data.
>>>
>>> Well, you'd have to return the original value for Strings, Numbers,
>>> etc. But there is a pattern [ ... ]:
>>>
>>> | myData = JSON.parse(text, function (key, value) {
>>> | var type;

BTW, the separate declaration here does not make much sense. Since
variable instantiation is performed before execution, you can declare
and initialize the variable in one statement. Since you do not use the
variable outside of the block, there is also no reason to declare it
outside (if we assumed that there was block scoping).

>>> | if (value && typeof value === 'object') {
>>> | type = value.type;
>>> | if (typeof type === 'string' &&
>>> | typeof window[type] === 'function') {
>>> | return new (window[type])(value);
>>> | }
>>> | }
>>> | return value;
>>> | });
>>>
>>> You could use this by adding "type":
>>>
>>> var people = [{type: "Person", first: "Thomas", last: "Lahn"}];
>>
>> [...]
>> In addition, this only works with constructors that are properties of
>> the Global Object; if we lose the needless reference check, it can work
>> with other constructors, too (applying eval() if necessary).
>
> I'm not sure I understand. Would you be willing to elaborate?

Sure. Let (for the sake of sanity) `_global' be a reference to the Global
Object, and `foo' holds the string value "Bar", then

_global[foo]

can only ever refer to

function Bar(/* ... */)
{
/* ... */
}

or

var Bar = function(/* ... */) {
/* ... */
};

if those are declared/defined so in the global execution context (only then
is `Bar' the name of a property of the Global Object).

It does not work for constructors declared/defined in a local execution
context --

function reviverWrapper(sConstructor)
{
/* ... */
}

function Foo()
{
function Bar(/* ... */)
{
/* ... */
}

JSON.parse(..., reviverWrapper("Bar"));
}

-- or for what has come to be called "namespaces":

var foo = {
Bar: function(/* ... */) {
/* ... */
}
};

However, if we would use eval() --

var myData = JSON.parse(text,
function (key, value) {
if (value && typeof value === 'object')
{
var type = value.type;
if (typeof type === 'string')
{
var C = eval(type);
if (typeof C === 'function')
{
return new C(value);
}
}
return value;
});

-- those two cases could be handled as well. (Of course, eval() has its
issues, too, but that is beside the point here.)

>>>> Second, `this' does not always refer to the passed object in the
>>>> reviver function; in JavaScript 1.8.1, [ ... ]
>>> Okay, I didn't realize this, but I'm not sure it matters. I hadn't
>>> thought of using "this" inside the function.
>
> (I should have explicitly said "inside the reviver function".)
>
>> You suggested to pass a reference to the constructor to JSON.parse().
>> In case you did not notice, the constructor uses `this' a lot.
>
> But if the constructor is used with "new" should the external value of
> "this" make any difference?

I do not know what "external value of 'this'" you are talking about;
`this' has only meaning in the execution context in which it is used.

I understood that *at first* you meant

JSON.parse(..., Person);

Maybe I misunderstood back then.


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
From: Scott Sauyet on
On Jan 26, 10:40 am, Thomas 'PointedEars' Lahn <PointedE...(a)web.de>
wrote:
> Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> Scott Sauyet wrote:
>>>
>>>> | myData = JSON.parse(text, function (key, value) {
>>>> |   var type;
>
> BTW, the separate declaration here does not make much sense.  Since
> variable instantiation is performed before execution, you can declare
> and initialize the variable in one statement.  Since you do not use the
> variable outside of the block, there is also no reason to declare it
> outside (if we assumed that there was block scoping).

Yes, I don't think I would use the code exactly as JSON.org supplied
it.

>> I'm not sure I understand.  Would you be willing to elaborate?
>
> Sure.  Let (for the sake of sanity) `_global' be a reference to the Global
> Object, and `foo' holds the string value "Bar" [ ... ]

Thank you for your very clear explanation. I thought you were headed
in a different direction.

You technique looks quite useful if we want a fairly generic reviver.
The alternative, of course it to explicitly supply those constructors
we need for a more specific reviver.



> >>>> Second, `this' does not always refer to the passed object in the
> >>>> reviver function; in JavaScript 1.8.1, [ ... ]
> >>> Okay, I didn't realize this, but I'm not sure it matters.  I hadn't
> >>> thought of using "this" inside the function.
>
> > (I should have explicitly said "inside the reviver function".)
>
> >> You suggested to pass a reference to the constructor to JSON.parse().
> >> In case you did not notice, the constructor uses `this' a lot.
>
> > But if the constructor is used with "new" should the external value of
> > "this" make any difference?
>
> I do not know what "external value of 'this'" you are talking about;
> `this' has only meaning in the execution context in which it is used.

I simply meant that the when running the constructor function the
execution context is not the same one used in the reviver function, so
the "this" references in the contructor function shold be as expected.


> I understood that *at first* you meant
>
>   JSON.parse(..., Person);
>
> Maybe I misunderstood back then.

Yes, perhaps I wasn't clear about something earlier. I have a hard
time imagining a Person constructor also serving as a reviver
function.

Cheers,

-- Scott