From: Johannes Baagoe on 21 Oct 2009 12:52 I haven't so far found an accurate explanation of the argument passings mechanism in javascript, and since it is a very basic question, I wonder what I have missed. According to the tutorial at https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Functions : Object parameters, e.g. objects, arrays and regular expressions, are passed to functions by reference In the course of wrestling with Csaba Gabor's Splicing exercise, taking that statement at its face value made my try the following : function insertArray(a1, a2, pos) { return a1 = a1.slice(0, pos).concat(a2, a1.slice(pos, a1.length)); } It doesn't work, a1 remains unchanged, contrary to what would happen if it had indeed been passed by reference like in Perl or FORTRAN. In javascript, if I understand correctly, no reassignment to a1 inside the function is going to be visible outside of the function. Now, the tutorial continues its statement like this : ; if you pass an object as a parameter to a function and the function changes the object's properties, that change is visible outside the function In my terminology, if the object itself cannot be reassigned, only its properties, that does constitutes a call by sharing, not a call by reference. But never mind the terminology, the point is rather that I find the argument passing mechanism somewhat confusing. Assuming var bar = ['a']; why, exactly, do the following functions yield the shown results ? function foo(a) {a = [1];} foo(bar); // bar[0] === 'a' function foo(a) {a[0] = 1;} foo(bar); // bar[0] === 1 function foo(a) {a = []; a[0] = 1;} foo(bar); // bar[0] === 'a' function foo(a) {a[0] = 1; a = [];} foo(bar); // bar[0] === 1 -- Johannes
From: Martin Honnen on 21 Oct 2009 13:28 Johannes Baagoe wrote: > I haven't so far found an accurate explanation of the argument passings > mechanism in javascript, and since it is a very basic question, > I wonder what I have missed. > > According to the tutorial at > https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Functions : > > Object parameters, e.g. objects, arrays and regular expressions, > are passed to functions by reference With Javascript it is all pass by value where values can be primitive values like number, boolean, string or can be object references. I think Java is similar. -- Martin Honnen http://msmvps.com/blogs/martin_honnen/
From: Thomas 'PointedEars' Lahn on 21 Oct 2009 13:52 We've been over this a thousand times or so, so I try to keep my answers short and concise Johannes Baagoe wrote: > I haven't so far found an accurate explanation of the argument passings > mechanism in javascript, and since it is a very basic question, > I wonder what I have missed. You have missed that object references are values. > According to the tutorial at > https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Functions : > > Object parameters, e.g. objects, arrays and regular expressions, > are passed to functions by reference That is wrong. Someone competent should use the Wiki functionality of MDC and correct it ASAP. > In the course of wrestling with Csaba Gabor's Splicing exercise, > taking that statement at its face value made my try the following : > > function insertArray(a1, a2, pos) { > return a1 = a1.slice(0, pos).concat(a2, a1.slice(pos, a1.length)); > } > > It doesn't work, a1 remains unchanged, contrary to what would happen > if it had indeed been passed by reference like in Perl or FORTRAN. > In javascript, if I understand correctly, no reassignment to a1 inside > the function is going to be visible outside of the function. Yes, if `a1' is a named argument it works like a local variable (that is good so because it is the only way to allow for default values). Arguments and local variables are properties of the same Variable Object of the entered execution context. > Now, the tutorial continues its statement like this : *Like* this? > ; if you pass an object as a parameter to a function and the > function changes the object's properties, that change is visible > outside the function That is somewhat correct; however, you do not pass the object, you pass a (one of several possible) reference(s) to the object. > In my terminology, if the object itself cannot be reassigned, only > its properties, that does constitutes a call by sharing, not a call > by reference. Simply forget about this terminology; it does not apply here (nor in many other object-oriented programming languages). > But never mind the terminology, the point is rather that > I find the argument passing mechanism somewhat confusing. It is actually very simple to understand if you accept the specified truth that object references are values (of the internal Reference type). > Assuming > > var bar = ['a']; > > why, exactly, do the following functions yield the shown results ? > > function foo(a) {a = [1];} foo(bar); // bar[0] === 'a' (Use pre-comment, not post-comment. Use /*... */ for documentation comments, `//' only for comments that disable code.) `a' is the identifier of a named argument. See above. > function foo(a) {a[0] = 1;} foo(bar); // bar[0] === 1 The passed value of `a' is a reference to an object, so a[0] resolves to the property named `0' of the referred object. Assigning a value to that property changes the value of that property (unless a setter is in place which prevents the change; not here). > function foo(a) {a = []; a[0] = 1;} foo(bar); // bar[0] === 'a' `a' is the identifier of a named argument which passed value is overwritten with a reference to a new Array instance (another object) encapsulating an empty array. As a result, changes are not visible in the calling execution context. > function foo(a) {a[0] = 1; a = [];} foo(bar); // bar[0] === 1 The passed value of `a' is a reference to an object, so a[0] resolves to the property named `0' of that object. Assigning a value to that property changes the value of the property (see above). Afterwards, `a' is assigned a reference to another, new Array instance (another object). `a' is the identifier of a named argument, so the latter change is not visible in the calling execution context. HTH. Please use a debugger with a Watches pane next time. The FAQ names several. <http://jibbering.com/faq/#posting> PointedEars -- Use any version of Microsoft Frontpage to create your site. (This won't prevent people from viewing your source, but no one will want to steal it.) -- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)
From: Jorge on 21 Oct 2009 14:01 On Oct 21, 6:52 pm, Johannes Baagoe <baa...(a)baagoe.com> wrote: > (...) > var bar = ['a']; > > why, exactly, do the following functions yield the shown results ? > > function foo(a) {a = [1];} foo(bar); // bar[0] === 'a' The value of 'a' on entry is a reference to bar. The value of 'a' is replaced with a reference to a new Array object [1]. > function foo(a) {a[0] = 1;} foo(bar); // bar[0] === 1 The value of 'a' on entry is a reference to bar. The element [0] of the array that 'a' refers to is assigned the value 1. > function foo(a) {a = []; a[0] = 1;} foo(bar); // bar[0] === 'a' The value of 'a' on entry is a reference to bar. The value of 'a' is replaced with a reference to a new Array object []. Element [0] of that new empty array is assigned the value 1. > function foo(a) {a[0] = 1; a = [];} foo(bar); // bar[0] === 1 The value of 'a' on entry is a reference to bar. The element [0] of the array that 'a' refers to is assigned the value 1. The value of 'a' is replaced with a reference to a new Array object []. -- Jorge.
From: Johannes Baagoe on 21 Oct 2009 14:19
Thomas 'PointedEars' Lahn : > We've been over this a thousand times or so, so I try to keep my answers > short and concise If it has been discussed a thousand times or so, shouldn't it be considered a FAQ ? -- Johannes |