primitives as function arguments in javascript - javascript

I'm learning JS here, and have a question regarding primitive values when passed in as arguments. Say I have a simple function:
var first = 5;
var second = 6;
function func(){
first+=second;
}
func();
alert(first); //outputs 11
So in this case the value of first becomes 11.. But if I try it by passing in first as an argument to the function, first remains 5..
var first = 5;
var second = 6;
function func(first){
first+=second;
}
func(first);
alert(first); //outputs 5
wondering if someone could explain this to me.

It happens because when you call function first() with no arguments, it uses the global var "first". But when you call function first(first), you says to browser that now first is a local variable (only inside the function) and it doesn't make any changes to the global var first. Here's the code:
var first = 5;
var second = 6;
function func(first){
first += second; //Local var "first" + global var "second"
alert(first); //Local var, outputs 11
}
func(first);
alert(first); //Global var, outputs 5

Due to Javascript's scoping, the scoped variable first is overriding the global variable first. In other words, you're adding second to the scoped version of first inside your function (which is scoped because you're declaring it inside the function), and the global version of first is unaffected.
If you remove the first's declaration from the function, Javascript goes for the next version of first it can find--in this case, the global one.

var first= 5;
var second= 6;
function func(first){
first+=second; // change the local first variable
}
func(first);
alert(first);//outputs 5 - the outer variable wasn't changed.
var first= 5; // global var
var second= 6;
function func(){ // first wasn't defined in the inner scope.
first+=second; // change the global bar
}
func();
alert(first);//outputs 11 - the outer variable was changed.

Mark Linus got your answer right, but I want to add an important note. Primitive values in JavaScript are always passed by value, where Array's and Object's are always passed by reference. Example:
var first = [ 'a', 'b' ];
function func( arr ) {
arr.push( 'c' );
}
func( first );
alert( first.join( ',' )); // output is 'a,b,c'
It gets more complicated if you have Objects in Objects or Arrays. Just remember that an alteration will affect all instances in your program.

Related

javascript, how to know the original name of a variable (not possible?) [duplicate]

I've got a feeling this might not be possible, but I would like to determine the original variable name of a variable which has been passed to a function in javascript. I don't know how to explain it any better than that, so see if this example makes sense.
function getVariableName(unknownVariable){
return unknownVariable.originalName;
}
getVariableName(foo); //returns string "foo";
getVariableName(bar); //returns string "bar";
This is for a jquery plugin i'm working on, and i would like to be able to display the name of the variable which is passed to a "debug" function.
You're right, this is very much impossible in any sane way, since only the value gets passed into the function.
This is now somehow possible thanks to ES6:
function getVariableName(unknownVariableInAHash){
return Object.keys(unknownVariableInAHash)[0]
}
const foo = 42
const bar = 'baz'
console.log(getVariableName({foo})) //returns string "foo"
console.log(getVariableName({bar})) //returns string "bar"
The only (small) catch is that you have to wrap your unknown variable between {}, which is no big deal.
As you want debugging (show name of var and value of var),
I've been looking for it too, and just want to share my finding.
It is not by retrieving the name of the var from the var but the other way around : retrieve the value of the var from the name (as string) of the var.
It is possible to do it without eval, and with very simple code, at the condition you pass your var into the function with quotes around it, and you declare the variable globally :
foo = 'bar';
debug('foo');
function debug(Variable) {
var Value = this[Variable]; // in that occurrence, it is equivalent to
// this['foo'] which is the syntax to call the global variable foo
console.log(Variable + " is " + Value); // print "foo is bar"
}
Well, all the global variables are properties of global object (this or window), aren't they?
So when I wanted to find out the name of my variables, I made following function:
var getName = function(variable) {
for (var prop in window) {
if (variable === window[prop]) {
return prop;
}
}
}
var helloWorld = "Hello World!";
console.log(getName(helloWorld)); // "helloWorld"
Sometimes doesn't work, for example, if 2 strings are created without new operator and have the same value.
Global w/string method
Here is a technique that you can use to keep the name and the value of the variable.
// Set up a global variable called g
var g = {};
// All other variables should be defined as properties of this global object
g.foo = 'hello';
g.bar = 'world';
// Setup function
function doStuff(str) {
if (str in g) {
var name = str;
var value = g[str];
// Do stuff with the variable name and the variable value here
// For this example, simply print to console
console.log(name, value);
} else {
console.error('Oh snap! That variable does not exist!');
}
}
// Call the function
doStuff('foo'); // log: foo hello
doStuff('bar'); // log: bar world
doStuff('fakeVariable'); // error: Oh snap! That variable does not exist!
This is effectively creating a dictionary that maps variable names to their value. This probably won't work for your existing code without refactoring every variable. But using this style, you can achieve a solution for this type of problem.
ES6 object method
In ES6/ES2015, you are able to initialize an object with name and value which can almost achieve what you are trying to do.
function getVariableName(unknownVariable) {
return Object.keys(unknownVariable)[0];
}
var foo = 'hello';
var output = getVariableName({ foo }); // Note the curly brackets
console.log(output);
This works because you created a new object with key foo and value the same as the variable foo, in this case hello. Then our helper method gets the first key as a string.
Credit goes to this tweet.
Converting a set of unique variable into one JSON object for which I wrote this function
function makeJSON(){ //Pass the variable names as string parameters [not by reference]
ret={};
for(i=0; i<arguments.length; i++){
eval("ret."+arguments[i]+"="+arguments[i]);
}
return ret;
}
Example:
a=b=c=3;
console.log(makeJSON('a','b','c'));
Perhaps this is the reason for this query
I think you can use
getVariableName({foo});
Use a 2D reference array with .filter()
Note: I now feel that #Offermo's answer above is the best one to use. Leaving up my answer for reference, though I mostly wouldn't recommend using it.
Here is what I came up with independently, which requires explicit declaration of variable names and only works with unique values. (But will work if those two conditions are met.)
// Initialize some variables
let var1 = "stick"
let var2 = "goo"
let var3 = "hello"
let var4 = "asdf"
// Create a 2D array of variable names
const varNames = [
[var1, "var1"],
[var2, "var2"],
[var3, "var3"]
]
// Return either name of variable or `undefined` if no match
const getName = v => varNames.filter(name => name[0] === v).length
? varNames.filter(name => name[0] === v)[0][1]
: undefined
// Use `getName` with OP's original function
function getVariableName(unknownVariable){
return getName(unknownVariable)
}
This is my take for logging the name of an input and its value at the same time:
function logVariableAndName(unknownVariable) {
const variableName = Object.keys(unknownVariable)[0];
const value = unknownVariable[variableName];
console.log(variableName);
console.log(value);
}
Then you can use it like logVariableAndName({ someVariable })

Why object method is rewrites the original objects? [duplicate]

This question already has answers here:
Is JavaScript a pass-by-reference or pass-by-value language?
(33 answers)
Closed 3 years ago.
Does JavaScript pass by references or pass by values?
Here is an example from JavaScript: The Good Parts. I am very confused about the my parameter for the rectangle function. It is actually undefined, and redefined inside the function. There are no original reference. If I remove it from the function parameter, the inside area function is not able to access it.
Is it a closure? But no function is returned.
var shape = function (config) {
var that = {};
that.name = config.name || "";
that.area = function () {
return 0;
};
return that;
};
var rectangle = function (config, my) {
my = my || {};
my.l = config.length || 1;
my.w = config.width || 1;
var that = shape(config);
that.area = function () {
return my.l * my.w;
};
return that;
};
myShape = shape({
name: "Unhnown"
});
myRec = rectangle({
name: "Rectangle",
length: 4,
width: 6
});
console.log(myShape.name + " area is " + myShape.area() + " " + myRec.name + " area is " + myRec.area());
Primitives are passed by value, and Objects are passed by "copy of a reference".
Specifically, when you pass an object (or array) you are (invisibly) passing a reference to that object, and it is possible to modify the contents of that object, but if you attempt to overwrite the reference it will not affect the copy of the reference held by the caller - i.e. the reference itself is passed by value:
function replace(ref) {
ref = {}; // this code does _not_ affect the object passed
}
function update(ref) {
ref.key = 'newvalue'; // this code _does_ affect the _contents_ of the object
}
var a = { key: 'value' };
replace(a); // a still has its original value - it's unmodfied
update(a); // the _contents_ of 'a' are changed
Think of it like this:
Whenever you create an object in ECMAscript, this object is formed in a mystique ECMAscript universal place where no man will ever be able to get. All you get back is a reference to that object in this mystique place.
var obj = { };
Even obj is only a reference to the object (which is located in that special wonderful place) and hence, you can only pass this reference around. Effectively, any piece of code which accesses obj will modify the object which is far, far away.
My two cents.... It's irrelevant whether JavaScript passes parameters by reference or value. What really matters is assignment vs. mutation.
I wrote a longer, more detailed explanation in this link.
When you pass anything (whether that be an object or a primitive), all JavaScript does is assign a new variable while inside the function... just like using the equal sign (=).
How that parameter behaves inside the function is exactly the same as it would behave if you just assigned a new variable using the equal sign... Take these simple examples.
var myString = 'Test string 1';
// Assignment - A link to the same place as myString
var sameString = myString;
// If I change sameString, it will not modify myString,
// it just re-assigns it to a whole new string
sameString = 'New string';
console.log(myString); // Logs 'Test string 1';
console.log(sameString); // Logs 'New string';
If I were to pass myString as a parameter to a function, it behaves as if I simply assigned it to a new variable. Now, let's do the same thing, but with a function instead of a simple assignment
function myFunc(sameString) {
// Reassignment... Again, it will not modify myString
sameString = 'New string';
}
var myString = 'Test string 1';
// This behaves the same as if we said sameString = myString
myFunc(myString);
console.log(myString); // Again, logs 'Test string 1';
The only reason that you can modify objects when you pass them to a function is because you are not reassigning... Instead, objects can be changed or mutated.... Again, it works the same way.
var myObject = { name: 'Joe'; }
// Assignment - We simply link to the same object
var sameObject = myObject;
// This time, we can mutate it. So a change to myObject affects sameObject and visa versa
myObject.name = 'Jack';
console.log(sameObject.name); // Logs 'Jack'
sameObject.name = 'Jill';
console.log(myObject.name); // Logs 'Jill'
// If we re-assign it, the link is lost
sameObject = { name: 'Howard' };
console.log(myObject.name); // Logs 'Jill'
If I were to pass myObject as a parameter to a function, it behaves as if I simply assigned it to a new variable. Again, the same thing with the exact same behavior but with a function.
function myFunc(sameObject) {
// We mutate the object, so the myObject gets the change too... just like before.
sameObject.name = 'Jill';
// But, if we re-assign it, the link is lost
sameObject = {
name: 'Howard'
};
}
var myObject = {
name: 'Joe'
};
// This behaves the same as if we said sameObject = myObject;
myFunc(myObject);
console.log(myObject.name); // Logs 'Jill'
Every time you pass a variable to a function, you are "assigning" to whatever the name of the parameter is, just like if you used the equal = sign.
Always remember that the equals sign = means assignment.
And passing a parameter to a function also means assignment.
They are the same and the two variables are connected in exactly the same way.
The only time that modifying a variable affects a different variable is when the underlying object is mutated.
There is no point in making a distinction between objects and primitives, because it works the same exact way as if you didn't have a function and just used the equal sign to assign to a new variable.
Function arguments are passed either by-value or by-sharing, but never ever by reference in JavaScript!
Call-by-Value
Primitive types are passed by-value:
var num = 123, str = "foo";
function f(num, str) {
num += 1;
str += "bar";
console.log("inside of f:", num, str);
}
f(num, str);
console.log("outside of f:", num, str);
Reassignments inside a function scope are not visible in the surrounding scope.
This also applies to Strings, which are a composite data type and yet immutable:
var str = "foo";
function f(str) {
str[0] = "b"; // doesn't work, because strings are immutable
console.log("inside of f:", str);
}
f(str);
console.log("outside of f:", str);
Call-by-Sharing
Objects, that is to say all types that are not primitives, are passed by-sharing. A variable that holds a reference to an object actually holds merely a copy of this reference. If JavaScript would pursue a call-by-reference evaluation strategy, the variable would hold the original reference. This is the crucial difference between by-sharing and by-reference.
What are the practical consequences of this distinction?
var o = {x: "foo"}, p = {y: 123};
function f(o, p) {
o.x = "bar"; // Mutation
p = {x: 456}; // Reassignment
console.log("o inside of f:", o);
console.log("p inside of f:", p);
}
f(o, p);
console.log("o outside of f:", o);
console.log("p outside of f:", p);
Mutating means to modify certain properties of an existing Object. The reference copy that a variable is bound to and that refers to this object remains the same. Mutations are thus visible in the caller's scope.
Reassigning means to replace the reference copy bound to a variable. Since it is only a copy, other variables holding a copy of the same reference remain unaffected. Reassignments are thus not visible in the caller's scope like they would be with a call-by-reference evaluation strategy.
Further information on evaluation strategies in ECMAScript.
As with C, ultimately, everything is passed by value. Unlike C, you can't actually back up and pass the location of a variable, because it doesn't have pointers, just references.
And the references it has are all to objects, not variables. There are several ways of achieving the same result, but they have to be done by hand, not just adding a keyword at either the call or declaration site.
JavaScript is pass by value.
For primitives, primitive's value is passed. For Objects, Object's reference "value" is passed.
Example with Object:
var f1 = function(inputObject){
inputObject.a = 2;
}
var f2 = function(){
var inputObject = {"a": 1};
f1(inputObject);
console.log(inputObject.a);
}
Calling f2 results in printing out "a" value as 2 instead of 1, as the reference is passed and the "a" value in reference is updated.
Example with primitive:
var f1 = function(a){
a = 2;
}
var f2 = function(){
var a = 1;
f1(a);
console.log(a);
}
Calling f2 results in printing out "a" value as 1.
In the interest of creating a simple example that uses const...
const myRef = { foo: 'bar' };
const myVal = true;
function passes(r, v) {
r.foo = 'baz';
v = false;
}
passes(myRef, myVal);
console.log(myRef, myVal); // Object {foo: "baz"} true
In practical terms, Alnitak is correct and makes it easy to understand, but ultimately in JavaScript, everything is passed by value.
What is the "value" of an object? It is the object reference.
When you pass in an object, you get a copy of this value (hence the 'copy of a reference' that Alnitak described). If you change this value, you do not change the original object; you are changing your copy of that reference.
"Global" JavaScript variables are members of the window object. You could access the reference as a member of the window object.
var v = "initialized";
function byref(ref) {
window[ref] = "changed by ref";
}
byref((function(){for(r in window){if(window[r]===v){return(r);}}})());
// It could also be called like... byref('v');
console.log(v); // outputs changed by ref
Note, the above example will not work for variables declared within a function.
Without purisms, I think that the best way to emulate scalar argument by reference in JavaScript is using object, like previous an answer tells.
However, I do a little bit different:
I've made the object assignment inside function call, so one can see the reference parameters near the function call. It increases the source readability.
In function declaration, I put the properties like a comment, for the very same reason: readability.
var r;
funcWithRefScalars(r = {amount:200, message:null} );
console.log(r.amount + " - " + r.message);
function funcWithRefScalars(o) { // o(amount, message)
o.amount *= 1.2;
o.message = "20% increase";
}
In the above example, null indicates clearly an output reference parameter.
The exit:
240 - 20% Increase
On the client-side, console.log should be replaced by alert.
★ ★ ★
Another method that can be even more readable:
var amount, message;
funcWithRefScalars(amount = [200], message = [null] );
console.log(amount[0] + " - " + message[0]);
function funcWithRefScalars(amount, message) { // o(amount, message)
amount[0] *= 1.2;
message[0] = "20% increase";
}
Here you don't even need to create new dummy names, like r above.
I can't see pass-by-reference in the examples where people try to demonstrate such. I only see pass-by-value.
In the case of variables that hold a reference to an object, the reference is the value of those variables, and therefore the reference is passed, which is then pass-by-value.
In a statement like this,
var a = {
b: "foo",
c: "bar"
};
the value of the 'a' is not the Object, but the (so far only) reference to it. In other words, the object is not in the variable a - a reference to it is. I think this is something that seems difficult for programmers who are mainly only familiar with JavaScript. But it is easy for people who know also e.g. Java, C#, and C.
Objects are always pass by reference and primitives by value. Just keep that parameter at the same address for objects.
Here's some code to illustrate what I mean (try it in a JavaScript sandbox such as https://js.do/).
Unfortunately you can't only retain the address of the parameter; you retain all the original member values as well.
a = { key: 'bevmo' };
testRetain(a);
document.write(' after function ');
document.write(a.key);
function testRetain (b)
{
document.write(' arg0 is ');
document.write(arguments[0].key);
b.key = 'passed by reference';
var retain = b; // Retaining the original address of the parameter
// Address of left set to address of right, changes address of parameter
b = {key: 'vons'}; // Right is a new object with a new address
document.write(' arg0 is ');
document.write(arguments[0].key);
// Now retrieve the original address of the parameter for pass by reference
b = retain;
document.write(' arg0 is ');
document.write(arguments[0].key);
}
Result:
arg0 is bevmo arg0 is vons arg0 is passed by reference after function passed by reference
Primitives are passed by value. But in case you only need to read the value of a primitve (and value is not known at the time when function is called) you can pass function which retrieves the value at the moment you need it.
function test(value) {
console.log('retrieve value');
console.log(value());
}
// call the function like this
var value = 1;
test(() => value);

Is there a form of C++ references in Javascript? [duplicate]

This question already has answers here:
Is JavaScript a pass-by-reference or pass-by-value language?
(33 answers)
Closed 3 years ago.
Does JavaScript pass by references or pass by values?
Here is an example from JavaScript: The Good Parts. I am very confused about the my parameter for the rectangle function. It is actually undefined, and redefined inside the function. There are no original reference. If I remove it from the function parameter, the inside area function is not able to access it.
Is it a closure? But no function is returned.
var shape = function (config) {
var that = {};
that.name = config.name || "";
that.area = function () {
return 0;
};
return that;
};
var rectangle = function (config, my) {
my = my || {};
my.l = config.length || 1;
my.w = config.width || 1;
var that = shape(config);
that.area = function () {
return my.l * my.w;
};
return that;
};
myShape = shape({
name: "Unhnown"
});
myRec = rectangle({
name: "Rectangle",
length: 4,
width: 6
});
console.log(myShape.name + " area is " + myShape.area() + " " + myRec.name + " area is " + myRec.area());
Primitives are passed by value, and Objects are passed by "copy of a reference".
Specifically, when you pass an object (or array) you are (invisibly) passing a reference to that object, and it is possible to modify the contents of that object, but if you attempt to overwrite the reference it will not affect the copy of the reference held by the caller - i.e. the reference itself is passed by value:
function replace(ref) {
ref = {}; // this code does _not_ affect the object passed
}
function update(ref) {
ref.key = 'newvalue'; // this code _does_ affect the _contents_ of the object
}
var a = { key: 'value' };
replace(a); // a still has its original value - it's unmodfied
update(a); // the _contents_ of 'a' are changed
Think of it like this:
Whenever you create an object in ECMAscript, this object is formed in a mystique ECMAscript universal place where no man will ever be able to get. All you get back is a reference to that object in this mystique place.
var obj = { };
Even obj is only a reference to the object (which is located in that special wonderful place) and hence, you can only pass this reference around. Effectively, any piece of code which accesses obj will modify the object which is far, far away.
My two cents.... It's irrelevant whether JavaScript passes parameters by reference or value. What really matters is assignment vs. mutation.
I wrote a longer, more detailed explanation in this link.
When you pass anything (whether that be an object or a primitive), all JavaScript does is assign a new variable while inside the function... just like using the equal sign (=).
How that parameter behaves inside the function is exactly the same as it would behave if you just assigned a new variable using the equal sign... Take these simple examples.
var myString = 'Test string 1';
// Assignment - A link to the same place as myString
var sameString = myString;
// If I change sameString, it will not modify myString,
// it just re-assigns it to a whole new string
sameString = 'New string';
console.log(myString); // Logs 'Test string 1';
console.log(sameString); // Logs 'New string';
If I were to pass myString as a parameter to a function, it behaves as if I simply assigned it to a new variable. Now, let's do the same thing, but with a function instead of a simple assignment
function myFunc(sameString) {
// Reassignment... Again, it will not modify myString
sameString = 'New string';
}
var myString = 'Test string 1';
// This behaves the same as if we said sameString = myString
myFunc(myString);
console.log(myString); // Again, logs 'Test string 1';
The only reason that you can modify objects when you pass them to a function is because you are not reassigning... Instead, objects can be changed or mutated.... Again, it works the same way.
var myObject = { name: 'Joe'; }
// Assignment - We simply link to the same object
var sameObject = myObject;
// This time, we can mutate it. So a change to myObject affects sameObject and visa versa
myObject.name = 'Jack';
console.log(sameObject.name); // Logs 'Jack'
sameObject.name = 'Jill';
console.log(myObject.name); // Logs 'Jill'
// If we re-assign it, the link is lost
sameObject = { name: 'Howard' };
console.log(myObject.name); // Logs 'Jill'
If I were to pass myObject as a parameter to a function, it behaves as if I simply assigned it to a new variable. Again, the same thing with the exact same behavior but with a function.
function myFunc(sameObject) {
// We mutate the object, so the myObject gets the change too... just like before.
sameObject.name = 'Jill';
// But, if we re-assign it, the link is lost
sameObject = {
name: 'Howard'
};
}
var myObject = {
name: 'Joe'
};
// This behaves the same as if we said sameObject = myObject;
myFunc(myObject);
console.log(myObject.name); // Logs 'Jill'
Every time you pass a variable to a function, you are "assigning" to whatever the name of the parameter is, just like if you used the equal = sign.
Always remember that the equals sign = means assignment.
And passing a parameter to a function also means assignment.
They are the same and the two variables are connected in exactly the same way.
The only time that modifying a variable affects a different variable is when the underlying object is mutated.
There is no point in making a distinction between objects and primitives, because it works the same exact way as if you didn't have a function and just used the equal sign to assign to a new variable.
Function arguments are passed either by-value or by-sharing, but never ever by reference in JavaScript!
Call-by-Value
Primitive types are passed by-value:
var num = 123, str = "foo";
function f(num, str) {
num += 1;
str += "bar";
console.log("inside of f:", num, str);
}
f(num, str);
console.log("outside of f:", num, str);
Reassignments inside a function scope are not visible in the surrounding scope.
This also applies to Strings, which are a composite data type and yet immutable:
var str = "foo";
function f(str) {
str[0] = "b"; // doesn't work, because strings are immutable
console.log("inside of f:", str);
}
f(str);
console.log("outside of f:", str);
Call-by-Sharing
Objects, that is to say all types that are not primitives, are passed by-sharing. A variable that holds a reference to an object actually holds merely a copy of this reference. If JavaScript would pursue a call-by-reference evaluation strategy, the variable would hold the original reference. This is the crucial difference between by-sharing and by-reference.
What are the practical consequences of this distinction?
var o = {x: "foo"}, p = {y: 123};
function f(o, p) {
o.x = "bar"; // Mutation
p = {x: 456}; // Reassignment
console.log("o inside of f:", o);
console.log("p inside of f:", p);
}
f(o, p);
console.log("o outside of f:", o);
console.log("p outside of f:", p);
Mutating means to modify certain properties of an existing Object. The reference copy that a variable is bound to and that refers to this object remains the same. Mutations are thus visible in the caller's scope.
Reassigning means to replace the reference copy bound to a variable. Since it is only a copy, other variables holding a copy of the same reference remain unaffected. Reassignments are thus not visible in the caller's scope like they would be with a call-by-reference evaluation strategy.
Further information on evaluation strategies in ECMAScript.
As with C, ultimately, everything is passed by value. Unlike C, you can't actually back up and pass the location of a variable, because it doesn't have pointers, just references.
And the references it has are all to objects, not variables. There are several ways of achieving the same result, but they have to be done by hand, not just adding a keyword at either the call or declaration site.
JavaScript is pass by value.
For primitives, primitive's value is passed. For Objects, Object's reference "value" is passed.
Example with Object:
var f1 = function(inputObject){
inputObject.a = 2;
}
var f2 = function(){
var inputObject = {"a": 1};
f1(inputObject);
console.log(inputObject.a);
}
Calling f2 results in printing out "a" value as 2 instead of 1, as the reference is passed and the "a" value in reference is updated.
Example with primitive:
var f1 = function(a){
a = 2;
}
var f2 = function(){
var a = 1;
f1(a);
console.log(a);
}
Calling f2 results in printing out "a" value as 1.
In the interest of creating a simple example that uses const...
const myRef = { foo: 'bar' };
const myVal = true;
function passes(r, v) {
r.foo = 'baz';
v = false;
}
passes(myRef, myVal);
console.log(myRef, myVal); // Object {foo: "baz"} true
In practical terms, Alnitak is correct and makes it easy to understand, but ultimately in JavaScript, everything is passed by value.
What is the "value" of an object? It is the object reference.
When you pass in an object, you get a copy of this value (hence the 'copy of a reference' that Alnitak described). If you change this value, you do not change the original object; you are changing your copy of that reference.
"Global" JavaScript variables are members of the window object. You could access the reference as a member of the window object.
var v = "initialized";
function byref(ref) {
window[ref] = "changed by ref";
}
byref((function(){for(r in window){if(window[r]===v){return(r);}}})());
// It could also be called like... byref('v');
console.log(v); // outputs changed by ref
Note, the above example will not work for variables declared within a function.
Without purisms, I think that the best way to emulate scalar argument by reference in JavaScript is using object, like previous an answer tells.
However, I do a little bit different:
I've made the object assignment inside function call, so one can see the reference parameters near the function call. It increases the source readability.
In function declaration, I put the properties like a comment, for the very same reason: readability.
var r;
funcWithRefScalars(r = {amount:200, message:null} );
console.log(r.amount + " - " + r.message);
function funcWithRefScalars(o) { // o(amount, message)
o.amount *= 1.2;
o.message = "20% increase";
}
In the above example, null indicates clearly an output reference parameter.
The exit:
240 - 20% Increase
On the client-side, console.log should be replaced by alert.
★ ★ ★
Another method that can be even more readable:
var amount, message;
funcWithRefScalars(amount = [200], message = [null] );
console.log(amount[0] + " - " + message[0]);
function funcWithRefScalars(amount, message) { // o(amount, message)
amount[0] *= 1.2;
message[0] = "20% increase";
}
Here you don't even need to create new dummy names, like r above.
I can't see pass-by-reference in the examples where people try to demonstrate such. I only see pass-by-value.
In the case of variables that hold a reference to an object, the reference is the value of those variables, and therefore the reference is passed, which is then pass-by-value.
In a statement like this,
var a = {
b: "foo",
c: "bar"
};
the value of the 'a' is not the Object, but the (so far only) reference to it. In other words, the object is not in the variable a - a reference to it is. I think this is something that seems difficult for programmers who are mainly only familiar with JavaScript. But it is easy for people who know also e.g. Java, C#, and C.
Objects are always pass by reference and primitives by value. Just keep that parameter at the same address for objects.
Here's some code to illustrate what I mean (try it in a JavaScript sandbox such as https://js.do/).
Unfortunately you can't only retain the address of the parameter; you retain all the original member values as well.
a = { key: 'bevmo' };
testRetain(a);
document.write(' after function ');
document.write(a.key);
function testRetain (b)
{
document.write(' arg0 is ');
document.write(arguments[0].key);
b.key = 'passed by reference';
var retain = b; // Retaining the original address of the parameter
// Address of left set to address of right, changes address of parameter
b = {key: 'vons'}; // Right is a new object with a new address
document.write(' arg0 is ');
document.write(arguments[0].key);
// Now retrieve the original address of the parameter for pass by reference
b = retain;
document.write(' arg0 is ');
document.write(arguments[0].key);
}
Result:
arg0 is bevmo arg0 is vons arg0 is passed by reference after function passed by reference
Primitives are passed by value. But in case you only need to read the value of a primitve (and value is not known at the time when function is called) you can pass function which retrieves the value at the moment you need it.
function test(value) {
console.log('retrieve value');
console.log(value());
}
// call the function like this
var value = 1;
test(() => value);

What is the difference in these two examples about JavaScript scope chain?

var a = 1;
function x() {
a = 2
console.log(a) // 2
}
x();
console.log(a); // 2
and :
var a = 1;
function x(p) {
p = 2
console.log(p) // 2
}
x(a);
console.log(a); // 1
Why is the output of the second example 1 instead of 2?
It's because your p variable exists only inside function x(p). So, you have a new space in memory, a copy variable a. In the first example, it's a pointer to memory address of variable a.
In other hand, objects have a "pass by reference", so if you do this:
var obj = { foo: 1 };
function x(paramObj) {
paramObj.foo = "2";
}
x(obj);
alert(obj.foo);
You will see "2" instead of "1".
Because function arguments are 'created' when the function gets executed.
var a = 1;
function x(p) {
p = 2
console.log(p) // 2
};
In this piece of code you create global variable a = 1; Then you pass it to the x function. Inside the function you set the given parameter to 2 and console.log it; But what really happens is this:
var a = 1;
function x(given_argument) {
var p = given_argument;
p = 2; // global a variable still equals 1;
console.log(p) // 2
};
This is because there are 2 types of variables in Javascript. Values like number, string, boolean etc that are just values and referential types like arrays, objects.
If you know C++ then this should lighten things up a bit. Here is equivalent of what happens in Javascript, written in C++:
// javascript
var a = 1; // plain value
// c++
int a = 1; // plain value
// javascript
var a = {}; // referential type, this is a pointer behind the scenes
// or
var a = new Object(); // if you prefer it this way
// c++
Object* a = new Object(); // this is a pointer to the object, but in C++ you make it a pointer explicitly, in Javascript this happens 'automagically'.
Referential types in Javascript are pointers, it means they can be changed from inside function, if passed as arguments. But if you pass normal value like number or boolean, it is declared inside the function, and it happens implicitly.
I hope it clarified the problem.

javascript arguments for beginner

Why the following code does not increase the variable a for 1 ?
var a =5;
function abc(y){
y++;
}
abc(a);
//a is 5 not 6 why?
but this does
var a = 5;
function abc(){
a++;
}
abc();
//a is 6
Because primitive values are passed by value in JavaScript.
To get the value to be updated, you could put a on an object and take advantage of the fact that objects are passed by reference (well, mostly, really a copy of the reference is passed, but we won't worry about that):
var obj = { a: 5 };
function abc(o){
o.a++;
}
abc(obj);
it takes the argument, but doesn't return any values.
y is just an argument for this I suggest two ways to do this
var a = 10
function increase(){
a++
}
increase();
var a = 10;
function increase(a){
return a++;
}
a = increase(a);
For a beginner's sake,
In simple words, when you call function by abc(a), 'a' is not passed to function abc but its value is copied to 'y'. (Its called pass by value). Since only 'y' in increased, you dont see an updated value of 'a'.

Categories

Resources