By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,631 Members | 892 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,631 IT Pros & Developers. It's quick & easy.

Script in an IFRAME can not call functions defined in the parent document?

P: n/a
In document "A.html" I have defined a function and within the document
body have included an IFRAME element who's source is document "B.html".
In document "B.html" I am trying to call the function defined in
"A.html", but every attempt results in an "is not a function" error. I
have tried to invoke the function using parent.document.funcname(),
top.document.funcname(), and various other identifying methods, but all
result in the above error. Any pointers would be greatly appreciated!

Example code, document "A.html":

<script>
function foo()
{
alert("foo!");
}
</script>
....
<IFRAME src="B.html">No frames?</IFRAME>

Example code, document "B.html":
<script>
parent.document.foo();
// also tried... top.document.foo();
</script>

Thanks in advance!
-Dave H.

Jul 23 '05 #1
Share this Question
Share on Google+
26 Replies


P: n/a
Try putting the call to foo in the iframe's body.onload event, and call
it with
top.foo() or parent.foo()

HTH

Jul 23 '05 #2

P: n/a
That worked, thanks! Actually I didn't even need to put it in the
onload event; just calling it as top.foo() rather than
top.document.foo() did the trick.

Thanks very much for the quick response!!

-Dave H.

Jul 23 '05 #3

P: n/a
Ivo
"Dave Hammond" wrote

parent.document.foo();
// also tried... top.document.foo();


Functions are not properties of the document, but of the window.
Try
parent.foo();
or
top.foo();

You may want to perform some checks first:
if( parent.foo ) { // function exists, so go ahead
parent.foo();
}

Still a nasty error may occur if the parent is not in the same domain as
your iframe'd page, for example if your page is among Google Images results,
it will be loaded in a frame with a different host, and accessing any
property of parent will break the script, unless you wrap the code in a
try/catch block. It is therefore usually safer to put your scripts in the
top-document, and copy the necessary parts to the iframe onload.

hth
ivo
http://4umi.com/web/javascript/


Jul 23 '05 #4

P: n/a
What's especially neat is that you can assign a new function to the top
window from the iframe, then load another document in the iframe, and
the top window's new function is still available.

Jul 23 '05 #5

P: n/a
Razzbar wrote:
What's especially neat is that you can assign a new function to the top
window from the iframe, then load another document in the iframe, and
the top window's new function is still available.


If I'm right, I believe that's because functions are primitive data
types in JS, like strings and numbers, so they're passed "by value" in
all operations, and not by reference.

So you're really ending up with a copy of the function, the same way
you would end up with a copy of a string or a number.

Granted, functions are *way* more useful to pass around this way than
strings or numbers.

Jul 23 '05 #6

P: n/a
Christopher J. Hahn wrote:
Razzbar wrote:
What's especially neat is that you can assign a new
function to the top window from the iframe, then load
another document in the iframe, and the top window's
new function is still available.
If I'm right, I believe that's because functions are
primitive data types in JS, like strings and numbers,


Functions are object in javascript. And like all other objects they can
have named properties added to them, and assigned values, at any time.
so they're passed "by value" in all operations, and
not by reference.

<snip>

Being objects they are passed by reference only.

Richard.
Jul 23 '05 #7

P: n/a
Richard Cornford wrote:
Christopher J. Hahn wrote:
Razzbar wrote:
What's especially neat is that you can assign a new
function to the top window from the iframe, then load
another document in the iframe, and the top window's
new function is still available.


If I'm right, I believe that's because functions are
primitive data types in JS, like strings and numbers,


Functions are object in javascript. And like all other objects they can
have named properties added to them, and assigned values, at any time.
so they're passed "by value" in all operations, and
not by reference.

<snip>

Being objects they are passed by reference only.

Richard.


Not to be argumentative, but if they are passed by reference only then
could you explain why the referant isn't freed, causing an error in the
case described by Razzbar?

I've been too busy to actually test the case, mind you, but I'm fairly
sure he's correct.

Jul 23 '05 #8

P: n/a


Christopher J. Hahn wrote:

Razzbar wrote:

What's especially neat is that you can assign a new
function to the top window from the iframe, then load
another document in the iframe, and the top window's
new function is still available.
Not to be argumentative, but if they are passed by reference only then
could you explain why the referant isn't freed, causing an error in the
case described by Razzbar?


What does pass by reference or value have to do with the case of frames?
If you have a global variable in one frame then it is a property of the
window object of the frame thus if the iframe document does
parent.varName = someExpression
then a global variable in the parent window is set and that variable
does not change if a new document is loaded into the iframe as the
iframe has its own window object with its own variables.
Whether that expression evaluates to a primitive value or a function
object does not matter at all, there is not even a method or function
with arguments involved where the term passing by reference or value
makes sense.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Jul 23 '05 #9

P: n/a
Martin Honnen wrote:
Christopher J. Hahn wrote:

Razzbar wrote:

>What's especially neat is that you can assign a new
>function to the top window from the iframe, then load
>another document in the iframe, and the top window's
>new function is still available.
Not to be argumentative, but if they are passed by reference only then
could you explain why the referant isn't freed, causing an error in the
case described by Razzbar?


What does pass by reference or value have to do with the case of frames?


Assign an object created in a child frame to a property of the parent
window, then navigate away from that document in the child frame and
attempt to manipulate the object in the parent window, and then maybe
you can tell me.
"Can't execute code from a free script."
If you have a global variable in one frame then it is a property of the
window object of the frame thus if the iframe document does
parent.varName = someExpression
then a global variable in the parent window is set and that variable
does not change if a new document is loaded into the iframe as the
iframe has its own window object with its own variables.
True, but if the variable is set as a reference (i.e. the object is
passed by reference to the assignment operator) then upon navigation of
the frame the referrant will been freed and the reference broken. In my
experience, further attempts to manipulate that object will result in
the error (in IE at least):
"Can't execute code from a freed script."

Try it out, as above.

This does not appear to be the case with functions or primitive values.
Whether that expression evaluates to a primitive value or a function
object does not matter at all, there is not even a method or function
with arguments involved where the term passing by reference or value
makes sense.
It is a function of operators that they receive values of some kind,
whether they be primitive values or references to objects (see also the
statement: ;+; ). I have commonly seen this provision of values to an
operator referred to as "passing". You might call it something else. It
makes no difference.


--

Martin Honnen
http://JavaScript.FAQTs.com/


Jul 23 '05 #10

P: n/a
Christopher J. Hahn wrote:
Richard Cornford wrote:
Christopher J. Hahn wrote:
Razzbar wrote:
> What's especially neat is that you can assign a new
> function to the top window from the iframe, then load
> another document in the iframe, and the top window's
> new function is still available.

If I'm right, I believe that's because functions are
primitive data types in JS, like strings and numbers,


Functions are object in javascript. And like all other objects they can
have named properties added to them, and assigned values, at any time.
so they're passed "by value" in all operations, and
not by reference.

<snip>

Being objects they are passed by reference only.

Richard.


Not to be argumentative, but if they are passed by reference only then
could you explain why the referant isn't freed, causing an error in the
case described by Razzbar?

I've been too busy to actually test the case, mind you, but I'm fairly
sure he's correct.


Richard,
Incidentally I did manage a *very* small test case and found that
by-reference-only appeared to be correct, though I didn't use frames or
anything.

But I really would appreciate it if you could explain to me why the
function object doesn't appear to be freed upon navigation like other
objects which are also members of the child window object. I think it
would clear up a lot of my confusion on this matter.

Jul 23 '05 #11

P: n/a


Martin Honnen wrote:
What does pass by reference or value have to do with the case of frames?
If you have a global variable in one frame then it is a property of the
window object of the frame thus if the iframe document does
parent.varName = someExpression
then a global variable in the parent window is set and that variable
does not change if a new document is loaded into the iframe as the
iframe has its own window object with its own variables.
Hmm... the iframe's document defines a function. The iframe's document
is a child of the iframe's window, so the iframe's function is part of
the of the iframe's window, which is part of the parent window...
Whether that expression evaluates to a primitive value or a function
object does not matter at all, there is not even a method or function
with arguments involved where the term passing by reference or value
makes sense.


But the question is, if top.foo() is a reference* to the foo() defined
in a document that has gone bye-bye, why does top.foo() still work?

If top.foo() = foo() //in the iframe's temporary document was an
assignment by value, it would make sense that it persists.

But if that's an assignment by reference, what would it be pointing to
after the defining document has changed?

Jul 23 '05 #12

P: n/a
Christopher J. Hahn wrote:
Richard Cornford wrote:
Christopher J. Hahn wrote:
If I'm right, I believe that's because functions are
primitive data types in JS, like strings and numbers,
Functions are object in javascript. And like all other
objects they can have named properties added to them,
and assigned values, at any time.
> so they're passed "by value" in all operations, and
> not by reference.

<snip>

Being objects they are passed by reference only.

Richard.


Not to be argumentative,


Don't worry about being argumentative.
but if they are passed by reference only then could you
explain why the referant isn't freed, causing an error in
the case described by Razzbar?
Superficial testing is the most likely explanation of the behaviour
described. The bottom line is that calling a function that has been
defined in a frame that has unloaded via a reference to that function in
another frame is not going to work cross-browser. Confidence acquired by
only testing browsers where it does work is no indicator of reliability.

Consider what would happen where it does work. Think about garbage
collection. If the containing frame refers to a function that originates
in (and so in some sense belongs to) another frame's global object then
that function should not be able to be garbage collected when the
contents of that other frame unload. And as the function's scope chain
refers to the global object then that global object should not be
garbage collectable, and as the global object refers to the document
(and indirectly to its contents) the document should not be garbage
collectable, and so on. So where it works it is a brilliant way of tying
up a big chunk of memory in exchange for the ability to use what is
potentially a tiny function. (And might even result in talk of memory
leaks, where the memory consumption would in reality be the expected
consequences of behaviour being specifically programmed).

However, the execution environment of an unloaded frame is (to some
degree or another, in different browsers) dismantled and functions and
objects referred to by properties in different frames may start
producing errors if used. that is certainly the case for functions in
some versions of Windows IE 6, and if it doesn't work in Windows IE 6
then it has no potential application in a commercial project.

That this should happen, and that the results should differ considerably
between browsers (and browser versions) is not particularly surprising
as ECMAScript is designed for one global object, and one execution
environment, rather than multiple interacting environments. There is
simply no specified mechanism for the interactions between environments.
I've been too busy to actually test the case, mind you,
but I'm fairly sure he's correct.


Do try it.

Richard.
Jul 23 '05 #13

P: n/a
Richard Cornford wrote:
Christopher J. Hahn wrote:
Richard Cornford wrote:
Christopher J. Hahn wrote:
If I'm right, I believe that's because functions are
primitive data types in JS, like strings and numbers,

Functions are object in javascript. And like all other
objects they can have named properties added to them,
and assigned values, at any time.

> so they're passed "by value" in all operations, and
> not by reference.
<snip>

Being objects they are passed by reference only.

Richard.
Not to be argumentative,


Don't worry about being argumentative.


Courtesy is a pretense with a purpose.
but if they are passed by reference only then could you
explain why the referant isn't freed, causing an error in
the case described by Razzbar?


Superficial testing is the most likely explanation of the behaviour
described. The bottom line is that calling a function that has been
defined in a frame that has unloaded via a reference to that function in
another frame is not going to work cross-browser. Confidence acquired by
only testing browsers where it does work is no indicator of reliability.

Consider what would happen where it does work. Think about garbage
collection. If the containing frame refers to a function that originates
in (and so in some sense belongs to) another frame's global object then
that function should not be able to be garbage collected when the
contents of that other frame unload. And as the function's scope chain
refers to the global object then that global object should not be
garbage collectable, and as the global object refers to the document
(and indirectly to its contents) the document should not be garbage
collectable, and so on. So where it works it is a brilliant way of tying
up a big chunk of memory in exchange for the ability to use what is
potentially a tiny function. (And might even result in talk of memory
leaks, where the memory consumption would in reality be the expected
consequences of behaviour being specifically programmed).


But there are other functionalities inherent in the language itself
that allow for remote creation of objects without resorting to the
ill-considered and clumsy implementation implied by the behavior to
which you're referring. There is no reason for a JS implementor to make
garbage collection quirky.
However, the execution environment of an unloaded frame is (to some
degree or another, in different browsers) dismantled and functions and
objects referred to by properties in different frames may start
producing errors if used. that is certainly the case for functions in
some versions of Windows IE 6, and if it doesn't work in Windows IE 6
then it has no potential application in a commercial project.

That this should happen, and that the results should differ considerably
between browsers (and browser versions) is not particularly surprising
as ECMAScript is designed for one global object, and one execution
environment, rather than multiple interacting environments. There is
simply no specified mechanism for the interactions between environments.


There's no reason the window object need be considered the top-level
object internally, so there's no reason for implementors to consider
the window to be an environment as opposed to another object in the
scope chain.

The problem seems to stem from the ambiguity of the relationship
between a document and its window. It would seem more intuitive (to me,
anyway) that variables and objects created by a document should be
properties of the document, rather than the window. Again, this is
obviously not the language's fault as (to my knowledge), the language
itself doesn't provide window or document objects.

This would be another point wehere I would like to see the W3C weigh
in.
I've been too busy to actually test the case, mind you,
but I'm fairly sure he's correct.


Do try it.

Richard.


The ability to do things that I believe I should not expect to work is
something that I try to forget about, as it lends itself to bad
practice in other languages and/or past or future versions or other
implementations of the same language (like I mentioned with PERL's
automatic return of the value of the last expression in a function). To
me, thought should be just as portable as code.

Thanks for that excellent answer, Richard.


Sorry if any of what I've said makes little sense-- I've been pretty
swamped and my mind is scattered across many things at once. This week
I am thinking in PERL::threads+C. Next week I'll be thinking in
PHP/C+HTML again. The week after it'll be JS+PHP+NNTP+HTML, with some
MySQL on the side.

Jul 23 '05 #14

P: n/a
Richard Cornford wrote:
Christopher J. Hahn wrote:
Razzbar wrote:
What's especially neat is that you can assign a new
function to the top window from the iframe, then load
another document in the iframe, and the top window's
new function is still available.


If I'm right, I believe that's because functions are
primitive data types in JS, like strings and numbers,


Functions are object in javascript. And like all other objects they can
have named properties added to them, and assigned values, at any time.
so they're passed "by value" in all operations, and not by reference.

<snip>

Being objects they are passed by reference only.


No. The known pass-by-* scheme of programming languages implementing
pointers does not apply here. A JS reference is not a pointer.

Objects in JS are only available via an object reference. One could say
that those references are passed to methods by value and that value is the
object. If you see it this way, it is quite clear why

function foo(x, y)
{
x = {bar: 42};
y.foobar = 23;
}

var y = {}, z = {};
foo(y, z);

does not result in (pseudocode)

y == {bar: 42, foobar: 23}

but in

y == {}
z == {foobar: 23}

The value of the first reference variable is changed to be assigned
a reference to a *new* object, and the value of the second reference
variable (i.e. the object) is changed to have a new property.
PointedEars
Jul 23 '05 #15

P: n/a
Thomas 'PointedEars' Lahn wrote:

<snip>
function foo(x, y)
{
x = {bar: 42};
y.foobar = 23;
}

var y = {}, z = {};
foo(y, z);

does not result in (pseudocode)

y == {bar: 42, foobar: 23}
No one could ever expect that - that would be misunderstanding the
basics of scoping and assignment!
but in

y == {}
z == {foobar: 23}
That's true, but your example is, IMHO, too obscure to serve as a clear
demonstration of whichever point.

---
function foo(a, b) {
a = {bar: 42};
b.foobar = 23;
}

var y = {p:"y"}, z = {p:"z"};
foo(y, z);
---
The value of the first reference variable is changed to be assigned
a reference to a *new* object, and the value of the second reference
variable (i.e. the object) is changed to have a new property.


Explaining in what 'y' consist in the end, and why, would certainly help
to provide some insight on the way references and objects work in
javascript.
Regards,
Yep 'passing by reference'.
Jul 23 '05 #16

P: n/a
Yann-Erwan Perio wrote:
Thomas 'PointedEars' Lahn wrote:
function foo(x, y)
{
x = {bar: 42};
y.foobar = 23;
}

var y = {}, z = {};
foo(y, z);

does not result in (pseudocode)

y == {bar: 42, foobar: 23}


No one could ever expect that - that would be misunderstanding the
basics of scoping and assignment!


No, if objects were 'always "passed by reference"' (as understood in a
language implementing pointers) as Richard stated, then x would be a
pointer to the object and an assignment to x would change the globally
defined object y. It does not, because only the reference is changed
to point to another object.
but in

y == {}
z == {foobar: 23}


That's true, but your example is, IMHO, too obscure to serve as a clear
demonstration of whichever point.

---
function foo(a, b) {
a = {bar: 42};
b.foobar = 23;
}

var y = {p:"y"}, z = {p:"z"};
foo(y, z);
---


OK, that's more clear. However, if one understood scoping and the
pass-by-reference scheme, he would also understand my example.
The value of the first reference variable is changed to be assigned
a reference to a *new* object, and the value of the second reference
variable (i.e. the object) is changed to have a new property.


Explaining in what 'y' consist in the end, and why, would certainly help
to provide some insight on the way references and objects work in
javascript.


[x] done
PointedEars
Jul 23 '05 #17

P: n/a
Thomas 'PointedEars' Lahn wrote:
Richard Cornford wrote:
Christopher J. Hahn wrote:
Razzbar wrote:
What's especially neat is that you can assign a new
function to the top window from the iframe, then load
another document in the iframe, and the top window's
new function is still available.

If I'm right, I believe that's because functions are
primitive data types in JS, like strings and numbers,
Functions are object in javascript. And like all other objects they can
have named properties added to them, and assigned values, at any time.
so they're passed "by value" in all operations, and not by reference.

<snip>

Being objects they are passed by reference only.


No. The known pass-by-* scheme of programming languages implementing
pointers does not apply here. A JS reference is not a pointer.

Objects in JS are only available via an object reference. One could say
that those references are passed to methods by value and that value is the
object. If you see it this way, it is quite clear why


I don't see the effective difference between a reference passed by
value and a value passed by reference. Not in JS, anyway, which to my
knowledge provides no explicit means for referencing, dereferencing,
nor threading.

Either way, you end up with a reference to the value.

Functionally there's no difference, is there?

function foo(x, y)
{
x = {bar: 42};
y.foobar = 23;
}

var y = {}, z = {};
foo(y, z);

does not result in (pseudocode)

y == {bar: 42, foobar: 23}

but in

y == {}
z == {foobar: 23}
Even given the way of thinking that the referenced object is being
passed by reference, this is equally clear.

The only difference (and I wouldn't call it a "real" difference) is
that, by saying it is being passed by reference, there's an implied
step of dereferencing, which I'm assuming doesn't actually occur.

The value of the first reference variable is changed to be assigned
a reference to a *new* object, and the value of the second reference
variable (i.e. the object) is changed to have a new property.
Because we're not talking pointers, but references, right?

PointedEars


Jul 23 '05 #18

P: n/a
Christopher J. Hahn wrote:
Thomas 'PointedEars' Lahn wrote: I don't see the effective difference between a reference passed by
value and a value passed by reference. Not in JS, anyway, which to my
knowledge provides no explicit means for referencing, dereferencing,
nor threading.

Either way, you end up with a reference to the value.

Functionally there's no difference, is there?


There is, ref. <54****************@PointedEars.de>
The value of the first reference variable is changed to be assigned
a reference to a *new* object, and the value of the second reference
variable (i.e. the object) is changed to have a new property.


Because we're not talking pointers, but references, right?


Yes.
PointedEars
Jul 23 '05 #19

P: n/a
Thomas 'PointedEars' Lahn wrote:

Hi,

<snip>
function foo(x, y)
{
x = {bar: 42};
y.foobar = 23;
}

var y = {}, z = {};
foo(y, z);

does not result in (pseudocode)

y == {bar: 42, foobar: 23}
No one could ever expect that - that would be misunderstanding the
basics of scoping and assignment!

No, if objects were 'always "passed by reference"' (as understood in a
language implementing pointers) as Richard stated, then x would be a
pointer to the object and an assignment to x would change the globally
defined object y. It does not, because only the reference is changed
to point to another object.


Just to clarify : I was not referring to the pointers/references issue,
but simply to the fact that 'y' becoming {bar:42, foobar:23} would not
be possible, whichever perspective (reference or pointer) - y.foobar in
the function's body would indeed apply on the object behind 'z'. This is
why I suggested, later in my post, a change in the arguments' names.

<snip>
Regards,
Yep.
Jul 23 '05 #20

P: n/a
Thomas 'PointedEars' Lahn wrote:
Christopher J. Hahn wrote:
Thomas 'PointedEars' Lahn wrote:
I don't see the effective difference between a reference passed by
value and a value passed by reference. Not in JS, anyway, which to my
knowledge provides no explicit means for referencing, dereferencing,
nor threading.

Either way, you end up with a reference to the value.

Functionally there's no difference, is there?


There is, ref. <54****************@PointedEars.de>

(adding news:54****************@PointedEars.de for convenience)
The value of the first reference variable is changed to be assigned
a reference to a *new* object, and the value of the second reference
variable (i.e. the object) is changed to have a new property.


Because we're not talking pointers, but references, right?


Yes.
PointedEars

Point being, since we're talking about references, not pointers, what
difference does it make what process is gone through when it's entirely
transparent to the programmer and has the same end result?

Either way, you end up with a reference to an object.

Unless you somehow dereference the object, there's no reason to believe
that x = { } would change the thing originally referenced by x instead
of changing the value of x to be a reference to a new object.

To express it in terms of PERL, since I don't know C:
$x = {};
print $x . "\n";
print \%$x;
^D
HASH(0x15d5178)
HASH(0x15d5178)

Which is to say:
The value of $x is equal to the value of a reference to ( $x
dereferenced )

Which is to say:
It's still a reference to the same thing.

Hence func( $x ) is functionally equivalent (in terms of this
discussion) to func( \%$x ).

On the one hand you pass the value of a variable containing a
reference.
On the other you pass a reference to the thing referenced by the
variable.

How are they not functionally equivalent?

Sorry for the PERL-- I know it's not a language you've used
extensively, but JS has no syntactical equivalent, making it utterly
moot so far as I can see. Either way you end up with a reference to the
same value: the thing being referenced (object or hash), and there's
really no way to end up with anything but.

Since nobody's talking about passing around pointers, what's the issue?

Jul 23 '05 #21

P: n/a
Yann-Erwan Perio wrote:
Thomas 'PointedEars' Lahn wrote:
function foo(x, y)
{
x = {bar: 42};
y.foobar = 23;
}

var y = {}, z = {};
foo(y, z);

does not result in (pseudocode)

y == {bar: 42, foobar: 23}
No one could ever expect that - that would be misunderstanding the
basics of scoping and assignment! No, if objects were 'always "passed by reference"' (as understood in a
language implementing pointers) as Richard stated, then x would be a
pointer to the object and an assignment to x would change the globally
defined object y. It does not, because only the reference is changed
to point to another object.


Just to clarify : I was not referring to the pointers/references issue,
but simply to the fact that 'y' becoming {bar:42, foobar:23} would not
be possible,


Yes, however y == {bar: 42} would be possible with implicit dereferencing.
My bad.
whichever perspective (reference or pointer) - y.foobar in
the function's body would indeed apply on the object behind 'z'. This is
why I suggested, later in my post, a change in the arguments' names.


ACK
PointedEars
Jul 23 '05 #22

P: n/a
Thomas 'PointedEars' Lahn wrote:
Richard Cornford wrote: <snip>
Functions are object ... <snip>
so they're passed "by value" in all operations, and
not by reference.


Being objects they are passed by reference only.


No.


You mean they are passed by value? They are not.

The value of an object is the totality of its state, so languages that
pass objects by value create a snapshot clone of the object and make
that available to the function. Javascript never does that, not even
with functions as previously suggested in this thread.
The known pass-by-* scheme of programming languages
implementing pointers does not apply here.
What is the point of stating that something that wasn't mentioned and
doesn't apply is irrelevant?
A JS reference is not a pointer.
Nobody has proposed that a reference is a pointer. Nobody but you has
even mentioned pointers. That the mechanism of how an object is refereed
to by a value assigned as an object property is left to the language
implementer is irrelevant. We know that many object properties may refer
to the same object instance. We can call that a reference and never
concern ourselves with the internal details.
Objects in JS are only available via an object reference.
So they can only be available inside a function to which they are
presented as an argument as a reference to an object.
One could say that those references are passed to
methods by value
Yes you could. The odds are very good that a value that represents some
sort of reference to an object is actually copied in the process of
passing a reference to an object as a function argument. Thus the
reference itself is passed by value, but passing the value of a
reference is equivalent to passing the object referred to by reference
(the copy of the value of the reference will still refer to the same
object instance).
and that value is the object.
You would be better off saying that the value of a reference to an
object is a reference to an object.

Thinking in terms of the value of an object property that refers to an
object as being that object is going to cause confusion as soon as it is
apparent that many properties refer to the same object and so that many
values in diverse locations are all that one object (just writing it
down makes it a self-evident that it is confusing).

A great deal of what makes OO useful is that it renders abstract notions
tangible. The very use of the word 'Object' to describe something so
nebulous that (in javascript at least) we don't even care how it
manifests itself inside the computer is an indication of that. An object
instance is just that; one entity, which is created, has a life span and
is disposed off (in some way). It makes much more sense to think of many
values referring to that one object than of many values being that one
object.
If you see it this way, it is quite clear why

function foo(x, y)
{
So when execution reaches this point the 'x' property of the function's
execution context's activation/Variable object holds a value that is a
reference to the object that is also referred to by the value of the
global 'y' variable and its 'y' property refers to the same object as
the object referred to by the global 'z' variable.
x = {bar: 42};
And now the 'x' property of the Activation/Variable object has been
assigned a reference to a new object.
y.foobar = 23;
While the reference held in the 'y' property has been used to identify
the object that is also referred to by the global 'z' variable and
assign a new value to one of its properties.
}

var y = {}, z = {};
foo(y, z);

does not result in (pseudocode)

y == {bar: 42, foobar: 23}
There was no reason to ever expect that it would. Assuming you are
referring to the object referred to by the global 'y' variable then no
operations have been performed that could influence it.
but in

y == {}
z == {foobar: 23}

The value of the first reference variable is changed to be
assigned a reference to a *new* object,
I assume you mean the first reference _parameter_ here, as it is the
value of the parameter (as manifest in the corresponding named property
of the Activation/variable object) that was modified to be a reference
to a new object.
and the value of the second reference variable (i.e.
the object) is changed to have a new property.


The state of the object was changed, indirectly, via the reference to
the object passed to the function as its second parameter.

It is significant that even imprecisely worded you are forced to express
the behaviour of the code in terms of references to objects. In
javascript all objects are passed by reference.

Richard.
Jul 23 '05 #23

P: n/a
"Random" <ra*******@gmail.com> writes:
Either way, you end up with a reference to an object.
We're back to the defintion of call-by-value and call-by-reference now.

In call-by-value, you pass a value. The parameter is a new variable
referring to the value that was passed.

In call-by-reference, you don't pass a reference to the value, but to
a *variabel*. The parameter becomes an alias of the variable that
was passed. E.g., in C#, using reference parameters:

---
static void Foo(ref int x) {
x = 42;
}

static void Bar() {
int baz = 37;
Foo(ref baz);
Console.WriteLine("{0}", baz); // Outputs "42"
}
---

Call-by-reference means that a call can change the value of a variable
that is not in scope from the called function.
Javascript only has call-by-value. Some values are called "references",
but that should not be confuzed with the way parameters are passed.

Unless you somehow dereference the object, there's no reason to believe
that x = { } would change the thing originally referenced by x instead
of changing the value of x to be a reference to a new object.
In call-by-reference, it would change what "x" refers to. It will not
change the previous *value* that "x" referred to, only *what* value it
refers to.
To express it in terms of PERL, since I don't know C:
$x = {};
print $x . "\n";
print \%$x;
^D
HASH(0x15d5178)
HASH(0x15d5178)

Which is to say:
The value of $x is equal to the value of a reference to ( $x
dereferenced )

Which is to say:
It's still a reference to the same thing.
But try this in Perl:
---
#!perl
sub foo {
my ($x) = @_;
$$x = 42;
}

sub bar {
my $baz = 37;
foo(\$baz);
print $baz;
}

bar();
---

This is explicit passing of a reference to a variable. In languages
like C#, the support for that is more indirect (references to
variables are not first class values there).
On the one hand you pass the value of a variable containing a
reference.
On the other you pass a reference to the thing referenced by the
variable.


And both are passed by value. (If passing by reference, you pass
an l-value, not an r-value.)

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 23 '05 #24

P: n/a
"Richard Cornford" <Ri*****@litotes.demon.co.uk> writes:
Thomas 'PointedEars' Lahn wrote:
Richard Cornford wrote:
Being objects they are passed by reference only.
No.


You mean they are passed by value? They are not.


No, their reference is passed by value. Using the word "passed by
reference" suggests (well, duh :) pass by reference semantics, which
it doesn't have.
The value of an object is the totality of its state,
I would include its identity too, which is what separates objects from
structs.
so languages that pass objects by value create a snapshot clone of
the object and make that available to the function.
.... but when you include identity in the value of the object, then
that would not be correct value passing semantics either.

In fact, objects are not denotable or expressible values (they can't
be assigned to a variable, and you can't write an expression that
evalutes to an object). Only *references* to objects are denotable
and expressible values. The value of an object literal expression
is a reference to the object.

(That objects are neither denotable nor expressible goes for all other
OO languages that I know. (Which is not too many, but still ... :)

Objects are used (has messages sent to them, to be *really* OO)
through their references.

References are passed by value, as all other values in Javascript.

but passing the value of a reference is equivalent to passing the
object referred to by reference (the copy of the value of the
reference will still refer to the same object instance).
That is not the traditional meaning of "passing by reference". In
that, you pass an l-value, really a reference to a variable, not to
its value. The called function has an alias of the vairable, and can
change its value.
You would be better off saying that the value of a reference to an
object is a reference to an object.
To be absolutely pedantic:
Expressions have values and variables refer to values.
If a variable refers to a reference to an object, then the value of
the expression consisting of that variable is the reference to the
object.

When passing the variable by reference, that called function has
access to the variable, and can change what it refers to. The formal
parameter of the function becomes an alias of the variable.

When passing a value by reference, the formal parameter of the
function becomes a new variable referring to the value that was
passed.

It is significant that even imprecisely worded you are forced to express
the behaviour of the code in terms of references to objects. In
javascript all objects are passed by reference.


In Javascript, all object references are passed by value. Objects are
never passed at all.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 23 '05 #25

P: n/a
Lasse Reichstein Nielsen wrote:
In Javascript, all object references are passed by value.
Objects are never passed at all.


Thank you very much for expressing my thoughts this clearly :)
\V/ PointedEars
Jul 23 '05 #26

P: n/a
Lasse Reichstein Nielsen wrote:
"Richard Cornford" <Ri*****@litotes.demon.co.uk> writes:
Thomas 'PointedEars' Lahn wrote:
Richard Cornford wrote: Being objects they are passed by reference only.

No.
You mean they are passed by value? They are not.


No, their reference is passed by value. Using the word "passed by
reference" suggests (well, duh :) pass by reference semantics, which
it doesn't have.
The value of an object is the totality of its state,


I would include its identity too, which is what separates objects from
structs.
so languages that pass objects by value create a snapshot clone of
the object and make that available to the function.


... but when you include identity in the value of the object, then
that would not be correct value passing semantics either.

In fact, objects are not denotable or expressible values (they can't
be assigned to a variable, and you can't write an expression that
evalutes to an object). Only *references* to objects are denotable
and expressible values. The value of an object literal expression
is a reference to the object.

(That objects are neither denotable nor expressible goes for all other
OO languages that I know. (Which is not too many, but still ... :)

Objects are used (has messages sent to them, to be *really* OO)
through their references.

References are passed by value, as all other values in Javascript.

but passing the value of a reference is equivalent to passing the
object referred to by reference (the copy of the value of the
reference will still refer to the same object instance).


That is not the traditional meaning of "passing by reference". In
that, you pass an l-value, really a reference to a variable, not to
its value. The called function has an alias of the vairable, and can
change its value.


[really liberal snipping]
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'


Thank you for that really excellent explanation. Basically, my
understanding of the term "pass by reference" is what's incorrect.

Given that explanation, I can see why it doesn't apply here, since
we're not actually passing lvalues, just references.

Thanks!

Jul 23 '05 #27

This discussion thread is closed

Replies have been disabled for this discussion.