From: Stefan Weiss on 28 Oct 2009 10:59 On 27/10/09 10:04, GodsBoss wrote: > In javascript, you can't do this: > > // Let a be a variable with any value. > // Let doSomething be a function. > var b=a; > doSomething(a); > // a===b, in every case. .... except when doSomething closes over a and b ;-) var a = "any value"; var b = a; console.assert(a === b); // passes doSomething(a); console.assert(a === b); // fails function doSomething (unused) { a = "oh no"; } If doSomething can see a and b in the scope chain, it can change their values directly without the need to pass anything (by reference or value). I know you intended doSomething to be a function which actually "does something" with its argument; just wanted to point out that there are exceptions to your "in every case" conclusion. cheers, stefan
From: Jorge on 28 Oct 2009 13:54 On Oct 28, 3:59 pm, Stefan Weiss <krewech...(a)gmail.com> wrote: > > var a = "any value"; > var b = a; > > console.assert(a === b); // passes > doSomething(a); > console.assert(a === b); // fails > > function doSomething (unused) { > a = "oh no"; > } > > If doSomething can see a and b in the scope chain, it can change their > values directly without the need to pass anything (by reference or > value). I know you intended doSomething to be a function which > actually "does something" with its argument; just wanted to point out > that there are exceptions to your "in every case" conclusion. Even if not :-) function doSomething (f, d) { f(d); } (function () { var a = "any value"; var b = a; function a_setter (p) { a= p; } console.log(a === b); // passes doSomething(a_setter, "oh no !"); console.log(a === b); // fails })() -- Jorge.
From: Jorge on 31 Oct 2009 12:41 On Oct 24, 5:55 pm, Lasse Reichstein Nielsen <lrn.unr...(a)gmail.com> wrote: > Jorge <jo...(a)jorgechamorro.com> writes: > > On Oct 24, 1:30 am, Lasse Reichstein Nielsen <lrn.unr...(a)gmail.com> > > wrote: > >> Yes, it's definitly not call-by-reference. > > > Yes it is -effectively- when the argument is an object: call-by- > > reference === call-by-value where the value is a reference. > > Except that's now what "call-by-reference" means. > In call-by-reference you pass an L-value, which can be overwritten. > I.e., you can change the binding of an *existing* variable. > > Passing the reference to an object allows that object to be modified, > but it does not allow an existing variable to be overwritten. var o; function f (p) { p.x+= 1; } f( o = { x: 1 } ); console.log(o.x); // 2 If you consider the argument to be the Lvalue 'var o', 'o' was passed by copy. If you consider the argument to be the Rvalue object { x: 1 }, it's been passed by reference. No matter what, objects are always passed by reference, as if the call had been f({ x: 1 }); effectively === f(&{ x: 1 }); -- Jorge.
From: Lasse Reichstein Nielsen on 31 Oct 2009 13:49 Jorge <jorge(a)jorgechamorro.com> writes: > On Oct 24, 5:55�pm, Lasse Reichstein Nielsen <lrn.unr...(a)gmail.com> > wrote: >> Jorge <jo...(a)jorgechamorro.com> writes: >> > Yes it is -effectively- when the argument is an object: call-by- >> > reference === call-by-value where the value is a reference. >> >> Except that's now what "call-by-reference" means. >> In call-by-reference you pass an L-value, which can be overwritten. >> I.e., you can change the binding of an *existing* variable. >> >> Passing the reference to an object allows that object to be modified, >> but it does not allow an existing variable to be overwritten. > > var o; > function f (p) { p.x+= 1; } > f( o = { x: 1 } ); > console.log(o.x); // 2 > > If you consider the argument to be the Lvalue 'var o', 'o' was passed > by copy. > If you consider the argument to be the Rvalue object { x: 1 }, it's > been passed by reference. The pedantic detail here is that "passed by reference" isn't a well defined term with lots of history, but "call-by-reference" is. Depending on the interpretation, javascript might or might not have the former. It definitly doesn't have the latter: You can't pass an L-value. > No matter what, objects are always passed by reference, as if the call > had been f({ x: 1 }); effectively === f(&{ x: 1 }); Or, alternatively: Objects are not expressible/denotable[1] values. Object references are. The expression "{x:1}" creates an object, and it evaluates to a reference to that object. Those references are passed as values (all Javascript function calls are call-by-value). The property accessor operators (dot and square-bracket) dereference the reference to find and act on the object. That's what I prefer to call call-by-value with reference types A reference type is exactly one where only a reference to the type is expressible and denotable, not the type itself - like object types in Java, object types in C# (but not value types), and no types in C++. (Object references should not be confused with the internal specification Reference type, which is a combination of an object reference and a name). /L [1] As defined by Strachey. -- Lasse Reichstein Holst Nielsen 'Javascript frameworks is a disruptive technology'
From: Jorge on 1 Nov 2009 06:14
On Oct 31, 6:49 pm, Lasse Reichstein Nielsen <lrn.unr...(a)gmail.com> wrote: > (...) > The pedantic detail here is that "passed by reference" isn't a well > defined term with lots of history, but "call-by-reference" is. > Depending on the interpretation, javascript might or might not have > the former. It definitly doesn't have the latter: You can't pass an > L-value. > (...) It seems to me that calling it like that is an extended C and Pascal - elder- programmers' habit. In C we hadn't the Pascal syntax for "var parameters", but we could always achieve the same effect by passing the appropriate &thing. At the receiving end it was just a matter of dereferencing -explicitly, unlike in Pascal- the thing* as much -or as little- as needed. It walks like a duck and quacks like a duck, therefore, we may have inherited Pascal's terminology, which was either "passed by value" (for value parameters) or "passed by reference" (for var parameters). I'm talking about the (late) 70's and the 80's. I don't think that *call* by reference (the term) was ever used (then), we said either to "pass by reference" or said nothing (implying "by value"). The term Lvalue (and Rvalue) was used (rather rarely if at all) to mean that a thing/expression (result) could be placed at the right hand side of an assignment. It was not used -not at all- in explaining parameter passing. Neither in C nor in Pascal. At least not back then, afaik. It's one of these things that you only learned if you read the book (K&R) from cover to cover, unlike other must-know-and-well terms such as, let's say, pointers and handles and structs, for example. -- Jorge. |