473,545 Members | 2,115 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

function identifier vs. arguments.calle e

VK
I was getting this effect N times but each time I was in rush to just
make it work, and later I coudn't recall anymore what was the original
state I was working around. This time I nailed the bastard so posting
it before I forgot again...

By taking this minimum code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">

// 1)
(function refByCallee() {
arguments.calle e.foobar = 'foobar';
})();

// 2)
(function refByName() {
refByName.fooba r = 'foobar';
})();

if (typeof refByCallee != 'undefined') {
alert(typeof refByCallee.foo bar); // undefined
alert(typeof refByName.fooba r); // string
}
</script>
</head>
<body>
<h1>Demo</h1>
</body>
</html>

There are two issues here: the one is well-known and another I what I
want to ask about.

1) The known issue is the difference of how JavaScript and JScript are
treating function declarations within expression. In JScript it still
leads to a function reference added to the global namespace, just as
without any parenthesis.
This way on IE after executing 1) and 2) we have two new global named
functions while on other engines not.

2) What I'm not sure is how to explain that IE obviously makes
difference here between arguments.calle e and literal name. While
literal name acts as expected - see 2) - arguments.calle e points to
some other object instance disappearing right after the execution.

Any insides?

Dec 29 '06 #1
7 3196
VK escreveu:
I was getting this effect N times but each time I was in rush to just
make it work, and later I coudn't recall anymore what was the original
state I was working around. This time I nailed the bastard so posting
it before I forgot again...

By taking this minimum code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">

// 1)
(function refByCallee() {
arguments.calle e.foobar = 'foobar';
})();
if (typeof refByCallee != 'undefined') {
alert(typeof refByCallee.foo bar); // undefined
alert(typeof refByName.fooba r); // string
}
The bellow lines show you what happens (the "namedFunct ion" isn't the
same object that is returned by the function declaration).

var f = function namedFunction() {
//alert(namedFunc tion === arguments.calle e);
//alert(f === arguments.calle e);
arguments.calle e.property = '[I exist]';
};
namedFunction() ; //using namedFunction as callee
alert(namedFunc tion.property + "\n" + f.property);

f(); //using f as callee
alert(namedFunc tion.property + "\n" + f.property);
--
Jonas Raoni Soares Silva
http://www.jsfromhell.com
Dec 29 '06 #2
VK wrote:
I was getting this effect N times but each time I was in rush
to just make it work, and later I coudn't recall anymore what
was the original state I was working around.
And you wonder why nobody takes you seriously when you label yourself a
"programmer "?
This time I nailed the bastard so posting
it before I forgot again...
Well, there is no hope that you could analyse this for yourself.
By taking this minimum code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
"Minimum code" does not need a META element.
<script type="text/javascript">

// 1)
(function refByCallee() {
arguments.calle e.foobar = 'foobar';
})();

// 2)
(function refByName() {
refByName.fooba r = 'foobar';
})();

if (typeof refByCallee != 'undefined') {
alert(typeof refByCallee.foo bar); // undefined
alert(typeof refByName.fooba r); // string
}
</script>
</head>
<body>
<h1>Demo</h1>
</body>
</html>

There are two issues here: the one is well-known and
another I what I want to ask about.

1) The known issue is the difference of how JavaScript
and JScript are treating function declarations within
expression.
There is no sense in "function declarations within expression". Programs
and function bodies are made up of FunctionDeclara tions and Statements
(two mutually exclusive constructs), Expressions are components of
Statements. The code above only features FunctionExpress ions with
optional Identifiers.
In JScript it still leads to a function reference added
to the global namespace,
IE erroneously adds named properties referring to function objects to
the Variable object for the execution context in which the
FunctionExpress ions with optional Identifiers appears. That is only the
global object in the global execution context.
just as without any parenthesis.
Without the parenthesise the constructs are unambiguously
FunctionDeclara tion (to every ECMAScript engine).
This way on IE after executing 1) and 2) we have two
new global named functions while on other engines not.
On IE you actually have two named properties of the Variable object
referring to function objects _before_ the execution of 1) and 2). And
this fact is the biggest clue as to what IE is really doing when it
misinterprets this code.
2) What I'm not sure is how to explain that IE obviously
makes difference here between arguments.calle e and literal
name.
You mean a difference between the object referred to by -
arguments.calle e - and the object referred to by the Identifier.
While literal name acts as expected - see 2)
It only acts as expected if you appreciate the bug in IE. The
expectation derived from the language specification is that the
Identifier used outside of the function bodies should not resolve into
references to function objects, and inside the function bodies they
should refer to the same object as - arguments.calle e -. It is the
difference between the formal specification that Microsoft assert
JScript follows and the behaviour of JScript that allows this to be
labelled a bug.
- arguments.calle e points to some other object instance
disappearing right after the execution.
The - arguments.calle e - reference should refer to the function object
that is being executed, and it does. As that function object results
form the inline execution of a FunctionExpress ion and no reference to
that function object is assigned to any property of any other object in
the system you should expect that object to 'disappear' following its
execution.

Apart from failing to test for the existence of the properties of the
Variable object prior to the execution of the FunctionExpress ions (and
so not noticing that they do exist, and refer to function objects, at
that point), you have not verified that, for example, - refByCallee -
and - arguemnts.calle e - refer to the same object. The tests is simple:-

alert('(callee === refByCallee) '+(arguments.ca llee === refByCallee));

- and with:-

(function fn() {
alert('(callee === fn) '+(arguments.ca llee === fn));
arguments.calle e.foobar = 'foobar';
})();

- the result is false. The object referred to by the Identifier - fn -
is not the same object as referred to by - arguments.calle e - inside the
executing function object.

Meanwhile, with:-

fn();

(function fn() {
alert('(callee === fn) '+(arguments.ca llee === fn));
arguments.calle e.foobar = 'foobar';
})();

fn();

- the alerts are true, false and true (in that order). Prior to the
evaluation of the FunctionExpress ion an - fn - function exists, can be
called and is the object referred to by - arguments.calle e - when it is
executing. When the FunctionExpress ion is executed - argument.callee -
does not refer to the - fn - function, and after the execution of the
FunctionExpress ion a second call to the - fn - function again results in
the execution of a function object that's - arguments.calle e - refers to
the - fn - function.

The explanation for this is simply that there are two function objects
involved; a function object that is referred to by the property of the
Variable object and comes into existence prior to the execution of any
code for the execution context, and a second function object that comes
into existence as a result of the evaluation of the FunctionExpress ion.

The function object coming into existence with the evaluation of the
FunctionExpress ion is what is supposed to happen (the handling of the
optional Identifier is still wrong on IE, but then optional Identifiers
are not really expected to be used with FunctionExpress ions). So it is
the creation of the first function object that represents the
manifestation of the bug in IE. The fact that these functions, and
corresponding properties of the Variable object, come into existence
prior to the execution of any code for the execution context suggests
that the fault is in the variable instantiation stage of execution.
Specifically, that at the point of scanning for function declarations IE
is using criteria for identifying Function Declarations that are
considerably more crude than the formal syntax rules for a
FunctionDeclara tion. That is, it is looking for the - function keyword
followed by an Identifier followed by a matching set of braces and
taking any occurrences of that, regardless of context, as a Function
Declaration. And so finding, and acting upon, considerably more
FunctionDeclara tions than exist in the actual code.

This probably represents an attempt at an optimisation for speed. It has
been observed that IE is the fastest browser at parsing javascript
source (by the fact that its - eval - function and - Function -
constructor out perform all other environments) and being a bit lax on
the syntax rules may be key to this.

The consequences of this bug are largely insignificant as nobody should
be writing code with the expectation that the optional Identifier in a
FunctionExpress ion should be available outside of the resulting
function, and so not be attempting to refer to that function in that
way. Your own code, for example, is stupidly designed. If you wanted to
refer to named global functions (to use them as a vehicle for passing
data about) then it would be trivial (and more obvious) to have the
function objects created globally with FunctionDeclara tions. If stupidly
obtuse code is written then it likely will fall over implementation
bugs.

Richard.
Dec 29 '06 #3
VK

Jonas Raoni wrote:
The bellow lines show you what happens (the "namedFunct ion" isn't the
same object that is returned by the function declaration).

var f = function namedFunction() {
//alert(namedFunc tion === arguments.calle e);
//alert(f === arguments.calle e);
arguments.calle e.property = '[I exist]';
};
namedFunction() ; //using namedFunction as callee
alert(namedFunc tion.property + "\n" + f.property);

f(); //using f as callee
alert(namedFunc tion.property + "\n" + f.property);
Yes, I knew it already - but still thank you for answering. My question
was what kind of object arguments.calle e is in this case and what
mechanics is behind.

Dec 30 '06 #4
VK

Richard Cornford wrote:
"Minimum code" does not need a META element.
Not for a HTML source and especially not for a HTML with a script
sample - unless one has a guarantee that the sample will be always
first uploaded to a properly configured server setting charset in
Content-Type header and only then viewed from that server.

Otherwise IE users with View Encoding Auto-Select activated may hit
the "Korean issue" while trying to execute the sample with the most
strange results to expect. The results will be especially "visually
impressive" if the current IE has Hangul (Korean phonemic alphabet)
package installed :-)

Try this for instance on IE with Auto-Select activated:

<html>
<head>
<title>Demo</title>
</head>
<body>
<h1>+10-</h1>
<script type="text/javascript">
var foo = "a" + "A";
alert(foo);
</script>
</body>
</html>

This way rather than being dependant on circumstances or checking each
source for the "Korean issue vulnerability" one should *always* set
META with matching charset. For the majority of simple demos ISO-8859-1
does the needed trick.

At the same time the existing standards do not require to place
META-EQUIV with Content-Type on the page. This way the brave people are
welcome to disregard this advice. They are even welcome do not set
Content-Type anywhere at all because current RFCs specify default
charset for both HTML and XML. I'm personally glad to see as many of
such "standard informed" people as possible. This people is the
quickest and easiest source of money for any help desk including ours
:-)

Dec 30 '06 #5
VK

Richard Cornford wrote:
There is no sense in "function declarations within expression". Programs
and function bodies are made up of FunctionDeclara tions and Statements
(two mutually exclusive constructs), Expressions are components of
Statements. The code above only features FunctionExpress ions with
optional Identifiers.
Thanks for your explanations which are snipped in this reply but which
are gracefully read.

In relevance to "bug" vs "behavior specific" the matter doesn't seem as
straightforward as you stated IMHO. The question is whether function
declaration
function something() {
}
becomes function statement just because you have surrounded it by
parenthesis:
(function something() {
})

?

ECMA and Gecko seems thinking yes. Microsoft seems thinking no, and
this point has some merit IMHO. Function object cannot be in the
left-hand side of an expression. So in case like
(function something() {
})();
we either have a syntaxically incorrect statement or
FunctionDeclara tion.

You may shot now if you want to :-) - I just expressed my worthless
opinion :-)

Dec 30 '06 #6
VK wrote:
Richard Cornford wrote:
>There is no sense in "function declarations within expression".
Programs and function bodies are made up of FunctionDeclara tions
and Statements (two mutually exclusive constructs), Expressions
are components of Statements. The code above only features
FunctionExpres sions with optional Identifiers.

Thanks for your explanations which are snipped in this reply
but which are gracefully read.
Evidently much of it went straight over your head, which is not
unexpected.
In relevance to "bug" vs "behavior specific" the matter
doesn't seem as straightforward as you stated IMHO.
Your opinions are, as always, worthless. In this case you ignorance of
the syntax rules for javascript, the related concepts, and your
consequent inability to understand my explanation of the pertinent
details, is the reason for that.
The question is whether
function declaration
function something() {
}
becomes function statement
It is a FunctionExpress ion. The syntactic units relating to functions
are FunctionDeclara tion and FunctionExpress ion. Neither are Statements.
FunctionDeclara tions and Statements are the two types of component that
make up Programs and function bodies, and so are mutually exclusive.
Statements may contain Expressions and so may contain Function
Expressions, though the syntax rules explicitly forbid the possibility
of any Statement consisting of only a Function Expression (by excluding
the function keyword from the possible tokens that may commence an
ExpressionState ment).
just because you have surrounded it by
parenthesis:
(function something() {
})

?
Surrounding the FunctionExpress ion with parenthesise does exactly that,
as the only construct that may commence with an opening parenthesis
token is an ExpressionState ment, the only Expression that may commence
with an opening parenthesis is the "Grouping operator"
PrimaryExpressi on, and the "Grouping operator" PrimaryExpressi on is only
allowed to contain an Expression.

Even if the opening parenthesis do not commence the Statement, that is,
if they follow a MemberExpressio n and so would be interpreted as an
Arguments List (forming a CallExpression) that Arguments List is still a
list of zero or more Expressions.

And so if you wrap parentheses around - function Identifier<opt(
FormalParameter List<opt) { FunctionBody } - you do guarantee that what
you have just wrapped in parenthesise is a FunctionExpress ion (and so
part of a Statement) and absolute not a FunctionDeclara tion (as
Statements and Function Declarations are mutually exclusive).
ECMA and Gecko seems thinking yes. Microsoft seems
thinking no,
If Microsoft do not think that construct is a FunctionExpress ion why is
JScript creating a new function object when it evaluates the Expression?
and this point has some merit IMHO.
Your opinions are, as always, worthless.
Function object cannot be in the
left-hand side of an expression.
Nonsense. Values that represent references to function objects (which is
what a parenthesised FunctionExpress ion evaluates as) are always the
left hand side of CallExpressions (that is, every successful
function/method call that is ever executed). It is your habitual making
ridiculous statements like that helps renders your opinions worthless.
So in case like
(function something() {
})();
we either have a syntaxically incorrect statement or
FunctionDeclara tion.
It is a syntactically correct CallExpression, and represents a
syntactically correct ExpressionState ment.

You are neglecting to take seriously the often observed fact that
whenever you think something is the case the odds are better than 50/50
that it is not the case. Try to understand; the stuff in your head has
very little relationship with reality. You should not trust it.
You may shot now if you want to :-) - I just expressed my
worthless opinion :-)
You certainly did. It may help you progress towards some sort of
understanding of javascript is you did something about learning the
syntax of the language instead of trying to make it up off the top of
your head.

Richard.
Dec 31 '06 #7
VK

Richard Cornford wrote:
Surrounding the FunctionExpress ion with parenthesise does exactly that,
as the only construct that may commence with an opening parenthesis
token is an ExpressionState ment, the only Expression that may commence
with an opening parenthesis is the "Grouping operator"
PrimaryExpressi on, and the "Grouping operator" PrimaryExpressi on is only
allowed to contain an Expression.
With such magic power of parenthesis I could claim then my $1,000,000
for positively solving Entscheidungspr oblem. Because of
FunctionExpress ion in JavaScript being a derivative case of lambda
calculus, Entscheidungspr oblem is solved as easy and elegant as:

<html>
<head>
<title>Test</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">
window.alert(
(function a(){}) == (function b(){})
);
</script>
</head>
<body>
<h1>Demo</h1>
</body>
</html>

Take it as a New Year joke. Nappy New Year!
:-)

Dec 31 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2022
by: Richard A. DeVenezia | last post by:
foo() generates elements with event handlers that invoke foo function properties. Is this an abhorrent or misthought pattern ? It allows just the one occurence of identifier /foo/ to be changed to /whatever/ when need arises and everything should still work. function foo () { var callee = arguments.callee
4
3605
by: anonymous | last post by:
Thanks your reply. The article I read is from www.hakin9.org/en/attachments/stackoverflow_en.pdf. And you're right. I don't know it very clearly. And that's why I want to understand it; for it's useful to help me to solve some basic problem which I may not perceive before. I appreciate your help, sincerely.
13
1686
by: Jake Barnes | last post by:
I saw this sentence: "The last stage of variable instantiation is to create named properties of the Variable object that correspond with all the local variables declared within the function." here: http://jibbering.com/faq/faq_notes/closures.html
41
2505
by: Telmo Costa | last post by:
Hi. I have the following code: -------------------------------------- function Tunnel() { //arguments(???); } function Sum() { var sum = 0; for (i=0; i<arguments.length; i++) sum += arguments;
14
1627
by: António Marques | last post by:
Hi! I don't think I've ever been here, so I assume I'm addressing a bunch of nice people. Can you help me? I don't think there's a solution, but who knows. The thing is, picture a large project where you want some encapsulation. But a lot of it being grouping of what would otherwise be static members of the global namespace. So that...
7
1769
by: runsun pan | last post by:
I wanna check if an object is the *arguments* object of a function, is that possible? When we do: typeof(arguments) it always returns "object", doesn't seem to be helpful.
5
2467
by: reycri | last post by:
Hi, I need to be able to do this: var func = new Function("var me = <selfRef>; alert(me.params);"); func.params = "This is a test parameter"; window.setTimeout(func, 500); Basically, I need to add properties to a function object and access them within the function when it is executing. Therefore, I need to be
1
1893
by: INeedADip | last post by:
What is the difference between: function setupGrid( param ){......} and setupGrid = function( param ){......} Are there any advantages to doing one over the other?
7
2843
by: Gregor Kofler | last post by:
What is the best practice for removing anonymous functions? Something like (function() { doSomething(); arguments.callee = null; })(); seems to work (at least it triggers no errors or exceptions on FF, but is this really a working solution?
0
7401
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7656
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7808
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7423
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7757
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
4945
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3443
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1884
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1014
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.