HighDots Forums  

A little test

Javascript JavaScript language (comp.lang.javascript)


Discuss A little test in the Javascript forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Dmitry A. Soshnikov
 
Posts: n/a

Default A little test - 11-06-2009 , 03:59 AM






Hi,

I specially didn't mention in the name of the topic to what kind of
theme in ECMA-262-3 is test related.

I've just explained on one forum again about [this-value] and what
object it should refer, there was some interesting examples (one of
which I'd like to make as a test).

The test is simple (please, try to answer (to youselft) first without
checking of code execution, then, execute the code (if needed), see
the result and give the answer here).

var foo = {
bar: function () {
return this;
}
};

alert(foo.bar()); // this - ?
alert((foo.bar)()); // this - ?
alert((foo.bar = foo.bar)()); // this - ?

P.S.> also, I'd like that guys for whom this test is very simple are
wait for other to answers, and then, if will be difficulty of other
people, give your answers.

/ds

Reply With Quote
  #2  
Old   
abozhilov
 
Posts: n/a

Default Re: A little test - 11-06-2009 , 07:06 AM






On Nov 6, 10:59*am, "Dmitry A. Soshnikov" <dmitry.soshni... (AT) gmail (DOT) com>
wrote:

Quote:
alert(foo.bar()); // this - ?

11.2.3 Function Calls
6. If Type(Result(1)) is Reference, Result(6) is GetBase(Result(1)).
Otherwise, Result(6) is null.
7. If Result(6) is an activation object, Result(7) is null.
Otherwise, Result(7) is the same as Result(6).
8. Call the [[Call]] method on Result(3), providing Result(7) as the
this value and providing the list Result(2) as the
argument values.
Here Result(6) is returned value from GetBase(Result(1)).
foo.bar(); //this refer `object' who referred from `foo';

Quote:
alert((foo.bar)()); // this - ?
() return internal Reference type. After that see point 6 from
Function calls.

Here `this' again refer `object' who referred from `foo'.

Quote:
alert((foo.bar = foo.bar)()); // this - ?
= Assignment expression return GetValue(Reference);

(foo.bar = foo.bar) => return value of `bar' property in `object'
referred from `foo'.
So Result(6) in Function Calls is null and pass to internal [[Call]]
method `null' for the `this' value.

Quote:
10.2.3 Function Code
* The caller provides the this value. If the this value provided by
the caller is not an object (including the case
where it is null), then the this value is the global object.

alert((foo.bar = foo.bar)()); // this refer GlobalObject.

Regards and apologies for my english.
I will be happy, if somebody explain better from me.

Reply With Quote
  #3  
Old   
Dmitry A. Soshnikov
 
Posts: n/a

Default Re: A little test - 11-06-2009 , 07:26 AM



On Nov 6, 3:06*pm, abozhilov <fort... (AT) gmail (DOT) com> wrote:

Quote:
[...]
I will be happy, if somebody explain better from me.
[...]
Your explanation was very good and accurate, thanks.

But you know it (I asked to wait for other answers ), it was very
easy for those who know what reference type is and how the [this-
value] is determinate by the caller. Also here the main moment is
related that identifier resolution just resolves to which base object
is property related, returning value of Reference Type; it doesn't
call GetValue which is vice-versa from assignment expression on
returning of which we get value any but not Reference type - for call
expression this means to get base as [null] => [Global].

The same situations with [this-value] are in similar examples. e.g.:

(foo.bar || foo.other)(); // global
(foo.bar, foo.bar)(); // global
(function () {})(); // global

In the last one is already not a Reference Type, and no identifier
resolution is taking place as it's not an identifier.

Reply With Quote
  #4  
Old   
abozhilov
 
Posts: n/a

Default Re: A little test - 11-06-2009 , 09:45 AM



On Nov 6, 2:26*pm, "Dmitry A. Soshnikov" <dmitry.soshni... (AT) gmail (DOT) com>
wrote:

Quote:
(foo.bar || foo.other)(); // global
(foo.bar, foo.bar)(); // global
(function () {})(); // global
Yes, in previous post i forget very important part from specification.
11.2.1 Property Accessors and 11.1.2 Identifier Reference which
explain:

alert(foo.bar()); // this - ?
alert((foo.bar)()); // this - ?

Try it another test:

function bar()
{
return this;
}

var foo = {
bar: bar
};

window.alert(foo.bar()); //this ?
window.alert(Object(foo.bar)()); //this ?

window.alert((function(){return foo.bar;})()()); //this?

with(foo)
{
window.alert(this.bar()); //this ?
window.alert(bar()); //this ?
}

Reply With Quote
  #5  
Old   
Dmitry A. Soshnikov
 
Posts: n/a

Default Re: A little test - 11-06-2009 , 12:48 PM



On Nov 6, 5:45*pm, abozhilov <fort... (AT) gmail (DOT) com> wrote:
Quote:
On Nov 6, 2:26*pm, "Dmitry A. Soshnikov" <dmitry.soshni... (AT) gmail (DOT) com
wrote:

(foo.bar || foo.other)(); // global
(foo.bar, foo.bar)(); // global
(function () {})(); // global

Yes, in previous post i forget very important part from specification.
*11.2.1 Property Accessors and 11.1.2 Identifier Reference which
explain:

alert(foo.bar()); // this - ?
Yep, here is: Identifier resolution for [foo] + property accessor for
[.bar]; by MemberExpression.Identifier algorithm it will be reference
type with base [foo] and property name [bar]. So, [this-value] is
[bar].

Quote:
alert((foo.bar)()); // this - ?
The same + inside the grouping operator in which already Reference
Type value is passed. [this-value] is [bar].

Quote:
Try it another test:

function bar()
{
* * return this;

}

var foo = {
* * bar: bar

};

window.alert(foo.bar()); //this ?
[this-value] is [foo], as it's value of Reference Type is standing
from the left of call-brackets.

Quote:
window.alert(Object(foo.bar)()); *//this ?

Yep, ToObject will return the value of [foo.bar], that's no a
Reference Type, so [this-value] is [null] => [Global].

Quote:
window.alert((function(){return foo.bar;})()()); //this?

The same, value is returned, it's not a Reference Type, so [this-
value] is [null] => [Global].

Quote:
with(foo)
{
* * window.alert(this.bar()); //this ?
* * window.alert(bar()); //this ?

[...]

In the first call, [this] is the global object itself (in this
execution context - global context), so it's truly provided as base of
reference [this.bar], so [this-value] is [Global] without any
transformations.

In the second call identifier resolution is taking place for [bar], as
the result will be value of Reference Type with base [__withObject]
and property name [bar], where [__withObject] is an object inserted in
front of scope chain. So, [this-value] is [__withObject].

But, beside the activation object when it's used as the base object of
Reference Type and which transforms to [null] => [Global] for [this-
value], also [catch clause] of [try] when used as the based object
transforms to [null] => [Global]:

For activation object:

function foo() {
function bar() {}
bar(); // the same: AO.bar() => null.bar() => Global.bar();
}

For catch-clause:

try {
throw function () {
return this;
};
} catch (ex) {
alert(ex()); // ?
}

In the last example identifier resolution will return a value of
Reference Type with base [__catchClauseObject] and property name [ex],
where [__catchClauseObject] is an object inserted in front of scope
chain. But in difference from [with] which also inserts its object in
front of scope chain, [__catchClauseObject] base will be transformed
to [null] => [Global].

Reply With Quote
  #6  
Old   
VK
 
Posts: n/a

Default Re: A little test - 11-07-2009 , 10:02 AM



A little more practical exercise if no one minds:

<script type="text/javascript">
window.alert(window.navigator || 'undefined'); // alerts ?
var navigator = {'userAgent' : 'foobar'};
window.alert(window.navigator || 'undefined'); // alerts ?
</script>

1,000 self-assigned bonus points if one names a popular browser
where this code leads to a syntax error so never gets executed.

On a really practical level that comes to the old maskon and
demaskonizing problems, see for instance my old post from 2007:
http://groups.google.com/group/comp.lang.javascript/msg/65a858c19f383df0

Given a situation with a malicious script that shadows (maskonizes)
window.XMLHttpRequest with its own object that fully emulates the
native one plus sends copies of each data input to a 3rd party server.
Until the malicious library is fully removed from any wide use, out
emergency security patch has to ensure that each new XMLHttpRequest is
based on the default vendor's constructor and not on some 3rd party
runtime maskon. On detecting a maskonized environment the security
patch first tries to get the access to the real constructor; if it's
not possible on the given platform then warn the user and break the
code execution.

Reply With Quote
  #7  
Old   
VK
 
Posts: n/a

Default Re: A little test - 11-07-2009 , 11:57 AM



Quote:
A little more practical exercise if no one minds:

script type="text/javascript"
*window.alert(window.navigator || 'undefined'); // alerts ?
*var navigator = {'userAgent' : 'foobar'};
*window.alert(window.navigator || 'undefined'); // alerts ?
/script

1,000 self-assigned bonus points if one names a popular browser
where this code leads to a syntax error so never gets executed.
As not everyone may have each prominent browser installed, I am giving
the ROT13 encoded answers
( http://www.retards.org/projects/rot13/ if needed):

VR
haqrsvarq
[bowrpg Bowrpg]

Fnsnev
[bowrpg Anivtngbe]
[bowrpg Bowrpg]

Puebzr
[bowrpg Anivtngbe]
[bowrpg Bowrpg]

Bcren
haqrsvarq
[bowrpg Bowrpg]

Argfpncr 4.7
[bowrpg Anivtngbe]
[bowrpg Bowrpg]

Sversbk
flagnk reebe "erqrpynengvba bs pbafg anivtngbe"

Reply With Quote
  #8  
Old   
Richard Cornford
 
Posts: n/a

Default Re: A little test - 11-07-2009 , 09:14 PM



VK wrote:
Quote:
A little more practical exercise if no one minds:

script type="text/javascript"
window.alert(window.navigator || 'undefined'); // alerts ?
var navigator = {'userAgent' : 'foobar'};
window.alert(window.navigator || 'undefined'); // alerts ?
/script

1,000 self-assigned bonus points if one names a popular
browser where this code leads to a syntax error so never
gets executed.
snip

The error is not a syntax error, it is a runtime error, which means that
the code does get executed, up the point where the error is thrown
(which is during variable instantiation for the global execution
context).

Richard.

Reply With Quote
  #9  
Old   
VK
 
Posts: n/a

Default Re: A little test - 11-08-2009 , 02:20 AM



Richard Cornford wrote:
Quote:
The error is not a syntax error, it is a runtime error, which means that
the code does get executed, up the point where the error is thrown
(which is during variable instantiation for the global execution
context).
The code never gets executed in Fx (I guess we may reveal the "hero"
by now) as this slight code modification shows:

<script type="text/javascript">
window.alert('OK 1');
try {
window.alert(window.navigator || 'undefined'); // alerts ?
var navigator = {'userAgent' : 'foobar'};
window.alert(window.navigator || 'undefined'); // alerts ?
}
catch(e) {
window.alert(e.message);
}
finally {
window.alert('OK 2');
}
</script>

where neither of alerts ever appears. Unless of course we introduce
three stages for the code lifetime instead of the conventional two:
1) parsing stage (syntax errors)
2) var instantiation stage (this kind of errors)
3) execution stage (runtime errors interceptable by try-catch blocks)
It is possible but way too theoretical IMHO. Whatever error happens
before any statement executed so try-catch is useless - it is a syntax
one.

btw 1,000,000,000 bonus points if anyone points a Books of ECMA
prophetic passage suggesting that
var navigator;
clause prevents the code execution.

Reply With Quote
  #10  
Old   
Dmitry A. Soshnikov
 
Posts: n/a

Default Re: A little test - 11-08-2009 , 05:13 AM



On Nov 8, 10:20*am, VK <schools_r... (AT) yahoo (DOT) com> wrote:

Quote:
[...]
*var navigator;
clause prevents the code execution.

[...]
that because of extension implemented by SpiderMonkey (since v.1.5) -
[const] keyword which prevents redeclaration of the same identifier
name - no matter - will it be a new [const] or [var]. Also, current
Safari browser ES implementation (WebKit) has [const] support, but in
difference form SpiderMonkey it doesn't throws an exception sort of
"redeclaration of ...", but just ignore the next [const] or [var] for
the same identifier name.

const foo = 1;
var foo = 2; // error in FF, no error in Safari
alert(foo); // 1 - in Safari, no change was made in [var]

/ds

Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.