How can I describe the difference between these two value passing styles? - javascript

This is what I understand to be pass by reference in C (note: I am not a C programmer):
void foo(int* x) { // The value of the memory address passed into `foo` is copied into parameter `x`
*x = 1; // The memory address x is dereferenced(?) and the value at that location overwritten
}
int main() {
int a = 0;
foo(&a); // The value of the (starting?) memory address associated with `a` is found and supplied as an argument to the function call
// `a` is now `1`
}
In this way, regardless of the type of x (even if it is an object (a struct in C?)), changes made to x inside foo will be reflected in the scope of main, even if the entire object is replaced.
In JavaScript, primitives are simply copied around and this is simple enough to reason about.
But for objects, IIUC, the value of their memory address (or equivalent) is supplied to function foo, which superficially sounds similar to the C code above. However, if we assign a value to the identifier created by parameter x, this is not reflected in the scope of main.
function foo(x) {
x = { bam: 'this is bam' }; // The value of the memory address passed into `foo` is copied into parameter `x`
}
function main() {
let a = { bar: 'this is bar' };
foo(a); // The value of the memory address associated with `a` is found and supplied as an argument to the function call (?)
// `a` is unchaged
}
JavaScript is pass by value. For objects it is sometimes called pass-by-value-of-the-reference - fair enough - but in the C code above, the value of the reference (OK pointer) is also copied into the function. So how can I describe the differences between pass-by-reference and pass by value? Is the passing of values actually the same, but only the referencing/dereferencing behavior of the two languages different?

C passes everything by value1. Sometimes those values are pointer values; this is not the same thing as pass by reference.
In a true pass by reference system the formal parameter in the function definition designates the same object as the actual parameter in the function call (assuming the actual parameter isn’t a numeric literal, anyway). Whether that’s accomplished by using pointers or under the hood or through a different mechanism is a function of the implementation. This is never the case in C.
The expression *x in foo designates the same object as the expression a in main, but the formal parameter x is a separate object from a. The result of the expression &a is passed by value and stored in the unique object x.
x == &a // int * == int *
*x == a // int == int
Arrays are weird. Except when it is the operand of the sizeof or unary & operators, or is a string literal used to initialize a character array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array. When you pass an array expression as an argument to the function, the function receives a pointer to the first element, not a copy of the entire array. So unlike other argument types, changes to the contents of an array argument in a function are reflected in the caller. This is still not true pass by reference, however. This is just fallout from C’s somewhat unique array semantics.

Related

Does for...of in JS pass values or references? [duplicate]

I'm following some canvas tutorial. The code below is a snippet of that.
In this snippet, why would they not choose for runAnimation to be a simple boolean? I would think the x = !x statement would work anyways, but when i tried changing the code to use booleans, the code didn't work.
So, what's the difference between a boolean as primitive and a boolean as property of an object?
/*
* define the runAnimation boolean as an object
* so that it can be modified by reference
*/
var runAnimation = {
value: false
};
// add click listener to canvas
document.getElementById('myCanvas').addEventListener('click', function() {
// flip flag
runAnimation.value = !runAnimation.value;
All arguments are passed by "value" in JavaScript. This means that when an argument is passed, a copy of what's stored in the variable is passed.
Primitives (like booleans) store the actual data they represent and so, when a primitive is passed, a copy of the data is sent, resulting in two copies of the data. Changes to one, won't affect the other.
But, when you assign an object to a variable, the variable stores the memory location for where that object can be found, not the object itself. Passing an object as an argument results in a copy of the memory address being passed. In these cases, you may wind up with two variables that store the same memory address, so no matter which variable you use, the same one underlying object is affected.
In your scenario, you could certainly make it work with just a boolean variable, but it appears that the tutorial wants to encapsulate that into an object so that copies of the boolean data won't be floating around and there will be less chances of accidentally changing one variable but not another.
Here's some basic examples:
// This function takes a single argument, which it calls "input"
// This argument will be scoped to the function.
function foo(input){
// The function is going to alter the parameter it received
input = input + 77;
console.log(input);
}
var input = 100; // Here's a higher scoped variable also called "input"
foo(input); // We'll pass the higher scoped variable to the function
// Now, has the higher level scoped "input" been changed by the function?
console.log(input); // 100 <-- No, it hasn't because primitives pass a copy of their data
// ************************************************
// Now, we'll do roughly the same thing, but with objects, not primitives
function foo2(obj){
obj.someProp = 100;
console.log(obj.someProp);
}
var obj = {
someProp : 50
};
foo2(obj);
// Here, we see that the original object has been changed by the funciton we passed it to
console.log(obj.someProp);

Changing JavaScript function's parameter value using arguments array not working

I am learning JavaScript and am pretty confused about the arguments property array.
I have a function that takes a single argument and returns it. When I pass the parameter and reassign it using arguments[0] = value, it's updating the value.
function a(b) {
arguments[0] = 2;
return b;
}
console.log(a(1)); //returns 2
But when I call the same function with no parameters it returns undefined.
function a(b) {
arguments[0] = 2;
return b;
}
console.log(a()); //returns undefined
But even if I pass undefined, the value will update as well.
function a(b) {
arguments[0] = 2;
return b;
}
console.log(a(undefined)); //returns 2
I thought that if you do not pass a parameter to a JavaScript function, it automatically creates it and assigns the value to undefined and after updating it should reflect the updated value, right?
Also a() and a(undefined) are the same thing, right?
Assigning to arguments indicies will only change the associated argument value (let's call it the n-th argument) if the function was called with at least n arguments. The arguments object's numeric-indexed properties are essentially setters (and getters):
http://es5.github.io/#x10.6
Italics in the below are my comments on how the process relates to the question:
(Let) args (be) the actual arguments passed to the [[Call]] internal method
Let len be the number of elements in args.
Let indx = len - 1.
Repeat while indx >= 0, (so, the below loop will not run when no arguments are passed to the function:)
(assign to the arguments object being created, here called map:)
Add name as an element of the list mappedNames.
Let g be the result of calling the MakeArgGetter abstract operation with arguments name and env.
Let p be the result of calling the MakeArgSetter abstract operation with arguments name and env.
Call the [[DefineOwnProperty]] internal method of map passing ToString(indx), the Property Descriptor {[[Set]]: p, [[Get]]: g, [[Configurable]]: true}, and false as arguments.
So, if the function is invoked with no arguments, there will not be a setter on arguments[0], so reassigning it won't change the parameter at index 0.
The same sort of thing occurs for other indicies as well - if you invoke a function with 1 parameter, but the function accepts two parameters, assigning to arguments[1] will not change the second parameter, because arguments[1] does not have a setter:
function fn(a, b) {
arguments[1] = 'bar';
console.log(b);
}
fn('foo');
So
a() and a(undefined) are the same thing right?
is not the case, because the second results in an arguments object with a setter and a getter on index 0, while the first doesn't.
Note that this odd interaction between the arguments and the function parameters is only present in sloppy mode. In strict mode, changes to arguments won't have any effect on the value an individual argument identifier contains:
'use strict';
function a(b) {
arguments[0] = 2;
return b;
}
console.log(a(1)); //returns 1
ECMA 262 9.0 2018 describes this behaviour in 9.4.4 Arguments Exotic Objects with
NOTE 1:
The integer-indexed data properties of an arguments exotic object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function's execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. If the arguments object is an ordinary object, the values of its properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values.
In short,
if in 'sloppy mode', then all arguments are mapped to their named variables, if the length correspond to the given parameter, or
if in 'strict mode', then the binding is lost after handing over the arguments.
This is only readable in an older version of ECMA 262 7.0 2016. It describes this behaviour in 9.4.4 Arguments Exotic Objects with
Note 1:
For non-strict functions the integer indexed data properties of an arguments object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function's execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. For strict mode functions, the values of the arguments object's properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values.
it's because arguments it's not like a Array, it's a object with integer indexed data keys, and property length, And if length equal zero it's mean you don't have a arguments
function a(b) {
arguments[0] = 2;
console.log(arguments.length)
return b;
}
a(1); // length 1 returns 2
console.log(a()); // length 0 returns undefined
When you are not providing any parameter then arguments array has length equal to 0. Then you are trying to set the non existing element of array to 2 which causes returning undefined
You can simply test this with this snippet:
function a(b){
alert(arguments.length) // It will prompt 0 when calling a() and 1 when calling a(undefined)
arguments[0] = 2;
return b;
}
This is the undefined value definition from javascript spec :
primitive value used when a variable has not been assigned a value.
so if you do not specify the function return type it will return undefined.
so a() and a(undefined) it is not same thing. returning undefined is based on return type is defined or not.
for more clarification similar_problem
My understanding is that the arguments object only tracks what is passed into the function. Since you've not initially passed anything, b is not bound and at that point arguments is not 'tracking' b. Next, you assign a value to the initialised but empty Array-like object arguments and finally return b, which is undefined.
To delve into this further:
If a non-strict function does not contain rest, default, or destructured parameters, then the values in the arguments object do change in sync with the values of the argument variables. See the code below:
function func(a) {
arguments[0] = 99; // updating arguments[0] also updates a
console.log(a);
}
func(10); // 99
and
function func(a) {
a = 99; // updating a also updates arguments[0]
console.log(arguments[0]);
}
func(10); // 99
When a non-strict function does contain rest, default, or destructured parameters, then the values in the arguments object do not track the values of the arguments. Instead, they reflect the arguments provided when the function was called:
function func(a = 55) {
arguments[0] = 99; // updating arguments[0] does not also update a
console.log(a);
}
func(10); // 10
and
function func(a = 55) {
a = 99; // updating a does not also update arguments[0]
console.log(arguments[0]);
}
func(10); // 10
and
// An untracked default parameter
function func(a = 55) {
console.log(arguments[0]);
}
func(); // undefined
Source: MDN Web docs

Re-initialization array in called function

Arrays are passed by reference in javascript. That means arrays are mutable and can be changed in called function. Why am I not able to Re-initialization an array in called function?
This is also true for python
function calling(){
var arr = [1,2]
console.log(arr); //prints [1,2]
called(arr);
console.log(arr); //prints [1,2,3,4],but I was expecting [5,6]
}
function called(arr){
arr.push(3)
arr.push(4)
arr = [5,6]
}
calling()
UPDATE
I am seeking justification of (mutability, pass by reference, pass by assignment and re-initialization of an array)
Please don't post workaround and solution of the problem. I know how to get arr to print [5,6]
Arrays are passed by reference in javascript.
No, they aren't. ECMAScript/JavaScript is strictly pass-by-value. (More precisely, call-by-sharing, which is a special case of pass-by-value.)
That means arrays are mutable and can be changed in called function.
No, that's not what it means. It means exactly what it says: that the reference within the caller's scope to the array is passed as an argument into the function, and not the value.
Whether or not the array is mutable or not has nothing to with pass-by-reference vs. pass-by-value. ECMAScript is not a purely functional language, most objects can be mutated. Numbers, Symbols, and Strings are an exception.
Why am I not able to Re-initialization an array in called function?
You are trying to modify the reference within the caller's scope. That only works with pass-by-reference. ECMAScript is not pass-by-reference, whoever told you that is simply wrong.
This is also true for python
Python behaves identically to ECMAScript in this regard, yes, it is also pass-by-value.
Your confusion stems from the fact that you erroneously believe ECMAScript/JavaScript is pass-by-reference, when in fact it is not.
ECMAScript uses pass-by-value, or more precisely, a special case of pass-by-value where the value being passed is always a pointer. This special case is also sometimes known as call-by-sharing, call-by-object-sharing or call-by-object.
It's the same convention that is used by Java (for objects), C# (by default for reference types), Smalltalk, Python, Ruby and more or less every object-oriented language ever created.
Note: some types (e.g. Numbers) are actually passed directly by value and not with an intermediary pointer. However, since those are immutable, there is no observable behavioral difference between pass-by-value and call-by-object-sharing in this case, so you can greatly simplify your mental model by simply treating everything as call-by-object-sharing. Just interpret these special cases as internal compiler optimizations that you don't need to worry about.
Here's a simple example you can run to determine the argument passing convention of ECMAScript (or any other language, after you translate it):
function isEcmascriptPassByValue(foo) {
foo.push('More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value!');
foo = 'No, ECMAScript is pass-by-reference.';
return;
}
var bar = ['Yes, of course, ECMAScript *is* pass-by-value!'];
isEcmascriptPassByValue(bar);
console.log(bar);
// Yes, of course, ECMAScript *is* pass-by-value!,
// More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value!
def is_python_pass_by_value(foo):
foo[0] = 'More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value!'
foo = ['Python is not pass-by-reference.']
quux = ['Yes, of course, Python *is* pass-by-value!']
is_python_pass_by_value(quux)
print(quux[0])
# More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value!
If you are familiar with C#, it is a very good way to understand the differences between pass-by-value and pass-by-reference for value types and reference types, because C# supports all 4 combinations: pass-by-value for value types ("traditional pass-by-value"), pass-by-value for reference types (call-by-sharing, call-by-object, call-by-object-sharing as in ECMAScript), pass-by-reference for reference types, and pass-by-reference for value types.
(Actually, even if you don't know C#, this isn't too hard to follow.)
// In C#, struct defines a value type, class defines a reference type
struct MutableCell
{
public string value;
}
class Program
{
// the ref keyword means pass-by-reference, otherwise it's pass-by-value
// You must explicitly request pass-by-reference both at the definition and the call
static void IsCSharpPassByValue(string[] foo, MutableCell bar, ref string baz, ref MutableCell qux)
{
foo[0] = "More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value.";
foo = new string[] { "C# is not pass-by-reference." };
bar.value = "For value types, it is *not* call-by-sharing.";
bar = new MutableCell { value = "And also not pass-by-reference." };
baz = "It also supports pass-by-reference if explicitly requested.";
qux = new MutableCell { value = "Pass-by-reference is supported for value types as well." };
}
static void Main(string[] args)
{
var quux = new string[] { "Yes, of course, C# *is* pass-by-value!" };
var corge = new MutableCell { value = "For value types it is pure pass-by-value." };
var grault = "This string will vanish because of pass-by-reference.";
var garply = new MutableCell { value = "This string will vanish because of pass-by-reference." };
// the first two are passed by value, the other two by reference
IsCSharpPassByValue(quux, corge, ref grault, ref garply);
Console.WriteLine(quux[0]);
// More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value.
Console.WriteLine(corge.value);
// For value types it is pure pass-by-value.
Console.WriteLine(grault);
// It also supports pass-by-reference if explicitly requested.
Console.WriteLine(garply.value);
// Pass-by-reference is supported for value types as well.
}
}
If you want to get technical, Javascript is really only "pass by value" - it is not "pass by reference". When you pass an object (like an Array), you are passing by value and the value is a reference (a copy of a reference to the array, not a copy of the actual array). This means you can use the value reference to mutate the original object, but it's not an actual reference to the original variable so you can't affect the contents of the original variable itself (e.g. you can't cause that other variable to point at a new object).
Since this language jargon doesn't actually explain what is going on for many folks, what follows here is more of a description of how it works:
When you do:
arr = [5,6]
inside your function, you are just assigning a new array to the arr function argument. You've just instructed Javascript to take the arr argument variable and point it at a new array object. That has no effect at all on the original array object that was passed into the function. It still happily exists in its other life.
You could change that array like this:
function called(arr){
arr.push(3)
arr.push(4)
// now set arr back to [5,6]
arr[0] = 5;
arr[1] = 6;
arr.length = 2;
}
It's a bit of a misnomer to say arrays are passed by reference because it isn't really a full reference like you would find in C++, for example. Some people say it's "pass by sharing" or "pass by pointer". Some people even call it "pass by value, but the value is a reference" which is probably technically correct, but doesn't usually help newbies understand what is going on. In my brain (partly because I know C/C++), I think of it like "pass by pointer".
Though Javascript doesn't actually have it's own data type that is a pointer, passing an array works more like passing a pointer works in C++. If you index off the pointer, you are accessing the original object:
arr[0] = 5; // this changes the original object
But, if you reassign the pointer a new value:
arr = [5,6]; // this just makes arr point at a new and different array
Then, you are just making the pointer variable itself point at a new object and the original object still remains untouched.
So, in summary. If you reference arr as in arr.push(x), then you are mutating the original array object.
But, if you assign arr a new array as in arr = [5,6], then you are just telling Javascript that you want the arr variable to point at a new array. Your arr variable in that function now points at a different array than it did before. The original array can no longer be reached by this code. But any other code that was pointing at that original array is still pointing at that original array. If you know C/C++, it actually works fairly similarly to a pointer in C++.
Here's a simpler example that is outside of the context of a function argument:
var x = [1,2];
var y = x;
console.log(x); // [1,2]
console.log(y); // [1,2]
y = [3,4];
console.log(x); // [1,2]
console.log(y); // [3,4]
You've merely asked y to now point to a new array [3,4]. Assigning y to point to a new array does not affect the original array at all.
In this example, the variable y is like the arr function argument in your called() function. Assigning a new value to it doesn't change the original in any way.
In Python:
In [170]: def called(arr):
.....: arr.append(3)
.....: arr.append(4)
.....: arr=[5,6]
.....:
In [171]: arr=[1,2]
In [172]: called(arr)
In [173]: arr
Out[173]: [1, 2, 3, 4]
Initially in called, arr is a reference to the mutable list [1,2]. The 2 append calls modify that list. But the arr=[5,6] step reassigns the variable. The link to outside arr is broken, so there's no further change.
If I'd added a return arr statement to the call,
In [175]: called(arr)
Out[175]: [5, 6]
In [176]: arr
Out[176]: [1, 2, 3, 4, 3, 4]
I modify the global arr again, but return the [5,6].
called would be clearer if written:
def called(arr):
arr.append(3)
arr.append(4)
res=[5,6]
return res
The last 2 lines have nothing to do with initial arr argument, so there is not point in reusing the variable name.
For further illustration of what is going on, look at the object id at various points:
In [178]: def called(arr):
arr.append(3)
arr.append(4)
print(id(arr))
arr = [5,6]
.....: return arr
.....:
In [179]: id(arr)
Out[179]: 2999818796
In [180]: id(called(arr))
2999818796 # id of global arr
Out[180]: 2999999564 # id of returned list
In [181]: id(arr)
Out[181]: 2999818796

Is it not possible to set arguments that have not been provided, using arguments property

I was testing things. And discovered that i could not set arguments if i have not provided it.
Using arguments[1] etc.
Example:
function abc (a,b) {
arguments[1] = 'new value';
console.log(b);
}
abc('a');
It won't work.
I know i could set value like if (b=='undefined') b='default'; but why i can't like this. In other words this behavior is unexpected, isn't it?
On the other hand, if you do provide argument it will get changed!
calling function like this will output new value
abc('a','b');
is there a solution, if you wanted to set value using arguments[2] and pass argument when calling function.
after more testing it seems: b doesnt get connected with arguments[1] if not called.
My understanding is argument is dynamic whose length is set by number of arguments / parameters provided to the function.
In first case, you have provided only one parameter so size of argument is 1 and hence argument[1] should be out of bound, while in second case, you have argument of length 2 so you can change either parameter value by using its index.
After posting a terribly wrong answer, I took a look at the ECMA Spec and here is in code, what JavaScript does when the arguments object will be created:
function abc () {
var names = ["a", "b"]; //as normally provided in the function declaration: function (a, b)
var a, b;
var args = {};
var mappedNames = [];
args.length = arguments.length;
var index = args.length - 1;
//this is the crucial part. This loop adds properties to the arguments object
//and creates getter and setter functions to bind the arguments properties to the local variables
//BUT: the loop only runs for the arguments that are actually passed.
while (index >= 0) {
var val = arguments[index];
if (index < names.length) {
var name = names[index];
if (mappedNames.indexOf(name) === -1) {
mappedNames.push(name);
var g = MakeArgGetter(name);
var p = MakeArgSetter(name);
Object.defineProperty(args, index.toString(), {get : g, set : p, configurable : true});
}
}
args[index.toString()] = val;
index--;
}
function MakeArgGetter(name) {
return function zz(){
return eval(name);
};
}
function MakeArgSetter(name) {
return function tt(value) {
eval(name + " = value;");
};
}
console.log(args[0]); //ab
args[0] = "hello";
args[1] = "hello";
console.log(a); //hello
console.log(b); //undefined
}
abc('ab');
Note, that there is some more going on in the Spec and I simplyfied it here and there, but this is essentially what is happening.
What are you trying to achieve by this?
If you want to have "dynamic arguments" like abc('a) and abc('a', 'b') are both valid, but the first will set the missing argument to a default value, you either have to check for the arguments length and/or for all arguments values.
Suppose the following: abc('a', null) is given, what then? - depends on logic, can be good but can also be bad.
Given this, checking the argument vector isn't smarter but more cryptic and having something like if (b=='undefined') b='default' much straighter and better to understand.
TL;DR: Not possible per ECMA spec since arguments is binded to only formal parameters that match the provided arguments. Its recommended to only reference arguments and not alter it.
Examples: http://jsfiddle.net/MattLo/73WfA/2/
About Arguments
The non-strict arguments object is a bidirectional and mapped object to FormalParameterList, which is a list generated based on the number of provided arguments that map to defined parameters in the target function defintion/expression.
When control enters an execution context for function code, an arguments object is created unless (as specified in 10.5) the identifier arguments occurs as an Identifier in the function’s FormalParameterList or occurs as the Identifier of a VariableDeclaration or FunctionDeclaration contained in the function code. ECMA 5.1 spec (as of 03/26/2014)
arguments to variables / variables to arguments
Argument-to-variable mappings exist only internally when the method is invoked. Mappings are immutable and are created when a target function is invoked, per instance. The update bindings between the two is also disabled when the use strict flag is available within the scope of the function. arguments becomes strictly a reference and no longer a way to update parameters.
For non-strict mode functions the array index (defined in 15.4) named data properties of an arguments object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function’s execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. For strict mode functions, the values of the arguments object‘s properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values. ECMA 5.1 spec (as of 03/26/2014)
What about length?
arguments.length can be an indicator initially to determine how many formal parameters were met but it's unsafe since arguments can be changed without length ever updating automatically. length doesn't update because it's not a real array and therefore doesn't adhere to the Array spec.

Understanding how variables are passed

I just can't understand how variables are passed, why are some passed by reference while other by value?
Example:
var a=4;
var b=a;
b=b++;
alert(a);//unmodified 4
var c=["t","ttt"];
var d=c;
d=d.sort(function(x,y){return (y.length-x.length);});
alert(c);//modified ["ttt","t"]
Where can I find a list of what variables will work like the first example and which like the second? (booleans, strings, etc... there are too many to test them all by miself)
JavaScript is always pass by value.
It's very common to say that objects in JavaScript are pass by reference, however that is not true. In a true pass by reference language, you could pass a reference to an object's reference, and have it point to another object. This is not possible in JavaScript.
Take, for example, C#. By default everything in C# is pass by value, just like JavaScript.
void foo(string s) {
s = "passbyvalue";
}
string a = "original value";
foo(a);
// a is still "original value"
However, if you alter foo to use pass by reference, the behavior changes:
void foo(ref string s) {
s = "passbyreference";
}
string a = "original value";
foo(ref a);
// a is now "passbyreference"
In JavaScript, only the first example is possible.
In JavaScript, everything is pass by value. This includes the object reference (yes, it is confusing). The reference itself is a value (it's very much like a pointer). It merely contains an id that allows the runtime to look up the object that is most likely stored in its heap. When you pass an object to a function, you are actually copying its reference into the function
It may be a seemingly small, and even anal, difference. But it's a key difference. Languages that have true pass by reference such as C# and C++ allow you to do things that are simply not possible in languages like JavaScript. The above trite example is one.
Imagine everything in JavaScript as an object. Object references are copied by value, but object properties are still used by reference. So:
var a = {};
var b = a;
b = 'Blah';
console.log(a); // Still {}
and
var a = {};
var b = a;
b.test = 'Blah';
console.log(a); // Is now {test: 'Blah'}
To simplify things a little: properties are by reference, values are by value.
Usually you can check the method on MDN. For example, the sort method's documentation states (emphasis added):
Sorts the elements of an array in place and returns the array.
The "in place" there says it will modify the array.
All primitives (for example, numbers and booleans) are passed by value; all objects are passed by reference, although some (like String objects) are immutable (although still passed by reference).
All objects get passed by reference and values by value. (technically this is not true, but it explains the behaviour)

Categories

Resources