var a = 3;
var b = 5;
example(a, b);
function example(b, a) {
var result = b - a;
alert(result);
}
My question is looking at this I though the result would be 2 but its negative 2 can someone explain why please?
You've inverted the arguments in your function definition.
While you are calling (a,b), you are receiving (b,a). This means that you are passing:
example(3,5)
and receiving:
(b=3, a=5)
You then return:
(b-a) or (3-5)
which is -2.
The actual names of the parameters in the function don't matter. You're getting confused because wherever you found the example- they cleverly reversed the order of b and a. However the names in the parameter are just used in the function scope and don't affect variables of the same name outside of it. For example:
var a = 3;
var b = 5;
example(a, b);
function example(bacon, eggs) {
var result = bacon - eggs;
alert(result);
}
Would also return -2 because the first parameter we pass through to example is a (3) and the second is b (5) and 3-5 = -2. Doesn't matter what the name of the parameters in example actually are named- its important to keep this in mind.
There is no problem with your code. The problem is with your lecture of the code. The result is in fact, -2. Debug your code in Chrome Debugger or similar
var a = 3; // a equals 3
var b = 5; // b equals 5
example(a, b); // Replacing variables this is the same as example(3,5)
// Changing variables names so you don't get mixed up
function example(c, d) {
// Since you called example(3,5) then c = 3 and d = 5
var result = c - d; // This results in -2
alert(result);
}
Don't be confused with the variable names because in js, it works by the order of your function argument not by variable name of functions. To get what you want as output i.e 2, try like this.
example(b = 5, a = 3);
function example(b, a) {
var result = b - a;
alert(result);
}
If you've any confusion go to http://www.pythontutor.com/javascript.html and see what is happening under the hood.
What is the difference of accessing variables inside the function by as argument and without argument?
var a = 1;
var b = 2;
function x() {
var c = a + b;
console.log(c)
}
function y(a, b) {
var c = a + b;
console.log(c)
}
The key difference here is that y does not use anything other than the arguments provided to the function. As soon as you see the function call - say y(1, 2) - you know exactly what will happen. (Assuming at least that you are reasonably familiar with the function and what it does - but even if you aren't familiar with it, hopefully it has a name that makes it sufficiently clear.)
The contrast with x is that it reads from external (here global) variables a and b. In other words, it depends on inputs that are not explicitly provided to the function. This makes it much harder to understand what a call to x() will do, because it depends on the value of a and b - which may be assigned quite some distance away in the program. Indeed, perhaps their values can be changed, in different ways, and by other functions - in which case it is impossible to know exactly what x() will do without carefully studying the entirety of the program up until that call. Again, contrast that with y where we need only look at the call site, and nothing else.
While, in some practical situations, it is hard to avoid some sort of "global state", avoiding it as much as possible, and trying to keep the information that a function needs local to it - as in y - is unquestionably better design. It makes the code much easier to understand, and therefore much less likely to have bugs in it.
Within the scope of your second function, a and b refer to the arguments, not the global variables.
var a = 1
var b = 2
function exampleOne () {
console.log("example 1: ", a, b)
}
function exampleTwo (a, b) {
console.log("example 2: ", a, b)
}
exampleOne()
exampleTwo(3, 4)
exampleTwo()
The 3 cases have different purposes, some non exhaustive:
Inside a function:
Only if the variable have to be unloaded after the function call, unless it be returned
function helloworld() {
const words = ['hello', 'world'];
return words.join(' ');
}
As argument:
Every time you want to use an external value which change the result
function hello(name) {
return 'Hello ' + name;
}
From closure:
In others cases:
// inside a lambda
function upperThan(array, n) {
return array.filter(item => item > n);
}
// use a constant
const HELLO = 'Hi';
function sayHello(name) {
return HELLO + ' ' + name;
}
Javascript always pass by value so changing the value of the variable never changes the underlying primitive (String or number).
If you modify variables inside the function that is passed as argument then it does not change the value of orignal variable(Pass by value).
var a = 1;
var b = 2;
function x() {
var c = a + b;
a = c;
console.log(c)
}
function y(a, b) {
var c = a + b;
var a = c;
console.log(c)
}
y(a, b)
console.log(a)
console.log(b)
x()
console.log(a)
console.log(b)
How do I pass variables by reference in JavaScript?
I have three variables that I want to perform several operations to, so I want to put them in a for loop and perform the operations to each one.
Pseudocode:
myArray = new Array(var1, var2, var3);
for (var x = 0; x < myArray.length; x++){
// Do stuff to the array
makePretty(myArray[x]);
}
// Now do stuff to the updated variables
What is the best way to do this?
There is no "pass by reference" available in JavaScript. You can pass an object (which is to say, you can pass-by-value a reference to an object) and then have a function modify the object contents:
function alterObject(obj) {
obj.foo = "goodbye";
}
var myObj = { foo: "hello world" };
alterObject(myObj);
alert(myObj.foo); // "goodbye" instead of "hello world"
You can iterate over the properties of an array with a numeric index and modify each cell of the array, if you want.
var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
arr[i] = arr[i] + 1;
}
It's important to note that "pass-by-reference" is a very specific term. It does not mean simply that it's possible to pass a reference to a modifiable object. Instead, it means that it's possible to pass a simple variable in such a way as to allow a function to modify that value in the calling context. So:
function swap(a, b) {
var tmp = a;
a = b;
b = tmp; //assign tmp to b
}
var x = 1, y = 2;
swap(x, y);
alert("x is " + x + ", y is " + y); // "x is 1, y is 2"
In a language like C++, it's possible to do that because that language does (sort-of) have pass-by-reference.
edit — this recently (March 2015) blew up on Reddit again over a blog post similar to mine mentioned below, though in this case about Java. It occurred to me while reading the back-and-forth in the Reddit comments that a big part of the confusion stems from the unfortunate collision involving the word "reference". The terminology "pass by reference" and "pass by value" predates the concept of having "objects" to work with in programming languages. It's really not about objects at all; it's about function parameters, and specifically how function parameters are "connected" (or not) to the calling environment. In particular, note that in a true pass-by-reference language — one that does involve objects — one would still have the ability to modify object contents, and it would look pretty much exactly like it does in JavaScript. However, one would also be able to modify the object reference in the calling environment, and that's the key thing that you can't do in JavaScript. A pass-by-reference language would pass not the reference itself, but a reference to the reference.
edit — here is a blog post on the topic. (Note the comment to that post that explains that C++ doesn't really have pass-by-reference. That is true. What C++ does have, however, is the ability to create references to plain variables, either explicitly at the point of function invocation to create a pointer, or implicitly when calling functions whose argument type signature calls for that to be done. Those are the key things JavaScript doesn't support.)
Primitive type variables like strings and numbers are always passed by value.
Arrays and Objects are passed by reference or by value based on these conditions:
if you are setting the value of an object or array it is Pass by Value.
object1 = { prop: "car" };
array1 = [1,2,3];
if you are changing a property value of an object or array then it is Pass by Reference.
object1.prop = "car";
array1[0] = 9;
Code
function passVar(obj1, obj2, num) {
obj1.prop = "laptop"; // will CHANGE original
obj2 = { prop: "computer" }; //will NOT affect original
num = num + 1; // will NOT affect original
}
var object1 = {
prop: "car"
};
var object2 = {
prop: "bike"
};
var number1 = 10;
passVar(object1, object2, number1);
console.log(object1); // output: Object { prop: "laptop" }
console.log(object2); // output: Object { prop: "bike" }
console.log(number1); // ouput: 10
Workaround to pass variable like by reference:
var a = 1;
inc = function(variableName) {
window[variableName] += 1;
};
inc('a');
alert(a); // 2
And yup, actually you can do it without access a global variable:
inc = (function () {
var variableName = 0;
var init = function () {
variableName += 1;
alert(variableName);
}
return init;
})();
inc();
Simple Object
function foo(x) {
// Function with other context
// Modify `x` property, increasing the value
x.value++;
}
// Initialize `ref` as object
var ref = {
// The `value` is inside `ref` variable object
// The initial value is `1`
value: 1
};
// Call function with object value
foo(ref);
// Call function with object value again
foo(ref);
console.log(ref.value); // Prints "3"
Custom Object
Object rvar
/**
* Aux function to create by-references variables
*/
function rvar(name, value, context) {
// If `this` is a `rvar` instance
if (this instanceof rvar) {
// Inside `rvar` context...
// Internal object value
this.value = value;
// Object `name` property
Object.defineProperty(this, 'name', { value: name });
// Object `hasValue` property
Object.defineProperty(this, 'hasValue', {
get: function () {
// If the internal object value is not `undefined`
return this.value !== undefined;
}
});
// Copy value constructor for type-check
if ((value !== undefined) && (value !== null)) {
this.constructor = value.constructor;
}
// To String method
this.toString = function () {
// Convert the internal value to string
return this.value + '';
};
} else {
// Outside `rvar` context...
// Initialice `rvar` object
if (!rvar.refs) {
rvar.refs = {};
}
// Initialize context if it is not defined
if (!context) {
context = this;
}
// Store variable
rvar.refs[name] = new rvar(name, value, context);
// Define variable at context
Object.defineProperty(context, name, {
// Getter
get: function () { return rvar.refs[name]; },
// Setter
set: function (v) { rvar.refs[name].value = v; },
// Can be overrided?
configurable: true
});
// Return object reference
return context[name];
}
}
// Variable Declaration
// Declare `test_ref` variable
rvar('test_ref_1');
// Assign value `5`
test_ref_1 = 5;
// Or
test_ref_1.value = 5;
// Or declare and initialize with `5`:
rvar('test_ref_2', 5);
// ------------------------------
// Test Code
// Test Function
function Fn1(v) { v.value = 100; }
// Test
function test(fn) { console.log(fn.toString()); console.info(fn()); }
// Declare
rvar('test_ref_number');
// First assign
test_ref_number = 5;
test(() => test_ref_number.value === 5);
// Call function with reference
Fn1(test_ref_number);
test(() => test_ref_number.value === 100);
// Increase value
test_ref_number++;
test(() => test_ref_number.value === 101);
// Update value
test_ref_number = test_ref_number - 10;
test(() => test_ref_number.value === 91);
Yet another approach to pass any (local, primitive) variables by reference is by wrapping variable with closure "on the fly" by eval. This also works with "use strict". (Note: be aware that eval is not friendly to JavaScript optimizers, and also missing quotes around variable name may cause unpredictive results)
"use strict"
// Return text that will reference variable by name (by capturing that variable to closure)
function byRef(varName){
return "({get value(){return "+varName+";}, set value(v){"+varName+"=v;}})";
}
// Demo
// Assign argument by reference
function modifyArgument(argRef, multiplier){
argRef.value = argRef.value * multiplier;
}
(function(){
var x = 10;
alert("x before: " + x);
modifyArgument(eval(byRef("x")), 42);
alert("x after: " + x);
})()
Live sample: https://jsfiddle.net/t3k4403w/
There's actually a pretty sollution:
function updateArray(context, targetName, callback) {
context[targetName] = context[targetName].map(callback);
}
var myArray = ['a', 'b', 'c'];
updateArray(this, 'myArray', item => {return '_' + item});
console.log(myArray); //(3) ["_a", "_b", "_c"]
I personally dislike the "pass by reference" functionality offered by various programming languages. Perhaps that's because I am just discovering the concepts of functional programming, but I always get goosebumps when I see functions that cause side effects (like manipulating parameters passed by reference). I personally strongly embrace the "single responsibility" principle.
IMHO, a function should return just one result/value using the return keyword. Instead of modifying a parameter/argument, I would just return the modified parameter/argument value and leave any desired reassignments up to the calling code.
But sometimes (hopefully very rarely), it is necessary to return two or more result values from the same function. In that case, I would opt to include all those resulting values in a single structure or object. Again, processing any reassignments should be up to the calling code.
Example:
Suppose passing parameters would be supported by using a special keyword like 'ref' in the argument list. My code might look something like this:
//The Function
function doSomething(ref value) {
value = "Bar";
}
//The Calling Code
var value = "Foo";
doSomething(value);
console.log(value); //Bar
Instead, I would actually prefer to do something like this:
//The Function
function doSomething(value) {
value = "Bar";
return value;
}
//The Calling Code:
var value = "Foo";
value = doSomething(value); //Reassignment
console.log(value); //Bar
When I would need to write a function that returns multiple values, I would not use parameters passed by reference either. So I would avoid code like this:
//The Function
function doSomething(ref value) {
value = "Bar";
//Do other work
var otherValue = "Something else";
return otherValue;
}
//The Calling Code
var value = "Foo";
var otherValue = doSomething(value);
console.log(value); //Bar
console.log(otherValue); //Something else
Instead, I would actually prefer to return both new values inside an object, like this:
//The Function
function doSomething(value) {
value = "Bar";
//Do more work
var otherValue = "Something else";
return {
value: value,
otherValue: otherValue
};
}
//The Calling Code:
var value = "Foo";
var result = doSomething(value);
value = result.value; //Reassignment
console.log(value); //Bar
console.log(result.otherValue);
These code examples are quite simplified, but it roughly demonstrates how I personally would handle such stuff. It helps me to keep various responsibilities in the correct place.
Happy coding. :)
I've been playing around with syntax to do this sort of thing, but it requires some helpers that are a little unusual. It starts with not using 'var' at all, but a simple 'DECLARE' helper that creates a local variable and defines a scope for it via an anonymous callback. By controlling how variables are declared, we can choose to wrap them into objects so that they can always be passed by reference, essentially. This is similar to one of the Eduardo Cuomo's answer above, but the solution below does not require using strings as variable identifiers. Here's some minimal code to show the concept.
function Wrapper(val){
this.VAL = val;
}
Wrapper.prototype.toString = function(){
return this.VAL.toString();
}
function DECLARE(val, callback){
var valWrapped = new Wrapper(val);
callback(valWrapped);
}
function INC(ref){
if(ref && ref.hasOwnProperty('VAL')){
ref.VAL++;
}
else{
ref++;//or maybe throw here instead?
}
return ref;
}
DECLARE(5, function(five){ //consider this line the same as 'let five = 5'
console.log("five is now " + five);
INC(five); // increment
console.log("five is incremented to " + five);
});
Actually it is really easy. The problem is understanding that once passing classic arguments, you are scoped into another, read-only zone.
The solution is to pass the arguments using JavaScript's object-oriented design. It is the same as putting the arguments in a global/scoped variable, but better...
function action(){
/* Process this.arg, modification allowed */
}
action.arg = [["empty-array"], "some string", 0x100, "last argument"];
action();
You can also promise stuff up to enjoy the well-known chain:
Here is the whole thing, with promise-like structure
function action(){
/* Process this.arg, modification allowed */
this.arg = ["a", "b"];
}
action.setArg = function(){this.arg = arguments; return this;}
action.setArg(["empty-array"], "some string", 0x100, "last argument")()
Or better yet...
action.setArg(["empty-array"],"some string",0x100,"last argument").call()
JavaScript can modify array items inside a function (it is passed as a reference to the object/array).
function makeAllPretty(items) {
for (var x = 0; x < myArray.length; x++){
// Do stuff to the array
items[x] = makePretty(items[x]);
}
}
myArray = new Array(var1, var2, var3);
makeAllPretty(myArray);
Here's another example:
function inc(items) {
for (let i=0; i < items.length; i++) {
items[i]++;
}
}
let values = [1,2,3];
inc(values);
console.log(values);
// Prints [2,3,4]
Putting aside the pass-by-reference discussion, those still looking for a solution to the stated question could use:
const myArray = new Array(var1, var2, var3);
myArray.forEach(var => var = makePretty(var));
As we don't have javascript pass by reference functionality, the only way to do this is to make the function return the value and let the caller assign it:
So
"makePretty(myArray[x]);"
should be
"myArray[x] = makePretty(myArray[x]);"
This is in case you need assignment inside the function, if only mutation is necessary, then passing the object and mutating it should be enough
I know exactly what you mean. The same thing in Swift will be no problem. The bottom line is use let, not var.
The fact that primitives are passed by value, but the fact that the value of var i at the point of iteration is not copied into the anonymous function is quite surprising to say the least.
for (let i = 0; i < boxArray.length; i++) {
boxArray[i].onclick = function() { console.log(i) }; // Correctly prints the index
}
If you want to pass variables by reference, a better way to do that is by passing your arguments in an object and then start changing the value by using window:
window["varName"] = value;
Example:
// Variables with first values
var x = 1, b = 0, f = 15;
function asByReference (
argumentHasVars = {}, // Passing variables in object
newValues = []) // Pass new values in array
{
let VarsNames = [];
// Getting variables names one by one
for(let name in argumentHasVars)
VarsNames.push(name);
// Accessing variables by using window one by one
for(let i = 0; i < VarsNames.length; i += 1)
window[VarsNames[i]] = newValues[i]; // Set new value
}
console.log(x, b, f); // Output with first values
asByReference({x, b, f}, [5, 5, 5]); // Passing as by reference
console.log(x, b, f); // Output after changing values
I like to solve the lack of by reference in JavaScript like this example shows.
The essence of this is that you don't try to create a by reference. You instead use the return functionality and make it able to return multiple values. So there isn't any need to insert your values in arrays or objects.
var x = "First";
var y = "Second";
var z = "Third";
log('Before call:',x,y,z);
with (myFunc(x, y, z)) {x = a; y = b; z = c;} // <-- Way to call it
log('After call :',x,y,z);
function myFunc(a, b, c) {
a = "Changed first parameter";
b = "Changed second parameter";
c = "Changed third parameter";
return {a:a, b:b, c:c}; // <-- Return multiple values
}
function log(txt,p1,p2,p3) {
document.getElementById('msg').innerHTML += txt + '<br>' + p1 + '<br>' + p2 + '<br>' + p3 + '<br><br>'
}
<div id='msg'></div>
Using Destructuring here is an example where I have 3 variables, and on each I do the multiple operations:
If value is less than 0 then change to 0,
If greater than 255 then change to 1,
Otherwise dived the number by 255 to convert from a range of 0-255 to a range of 0-1.
let a = 52.4, b = -25.1, c = 534.5;
[a, b, c] = [a, b, c].map(n => n < 0 ? 0 : n > 255 ? 1 : n / 255);
console.log(a, b, c); // 0.20549019607843136 0 1
A swap() function would result in cleaner code (DRY) than doing the work inline. Unfortunately, the following function accomplished nothing because in JavaScript parameters are always pass-by-value:
function swap(a,b) { var temp=a; a=b; b=temp; }
Is there any way of writing a function that accomplished what this is attempting, particularly for numeric values?
I'm not impressed with the answers to this related question.
This answer has the right idea, but doesn't handle the general case.
As you correctly identified, since the parameters are passed by value you cannot write a function that replaces the block:
var a,b;
...
var tmp = a; a = b; b = tmp;
However, you can do it if both are values of an object:
var o = {};
o.a = 3;
o.b = 4;
function swap(obj) { var tmp = obj.a; obj.a = obj.b; obj.b = tmp; }
swap(o);
You can also generalize the swap:
function swap(obj, a, b) { var tmp = obj[a]; obj[a] = obj[b]; obj[b] = tmp; }
swap(o,'a','b')
You can also make this a prototype function:
Object.prototype.swap = function(a,b) { var tmp = this[a]; this[a] = this[b]; this[b] = tmp; }
o.swap('a','b')
With EMCAScript 6, you can abuse the destructuring assignment feature.
var x = 1, y = 2;
console.log(`x = ${x}, y = ${y}`);
[x, y] = [y, x];
console.log(`x = ${x}, y = ${y}`);
MDN actually has this as one of its examples.
EDIT:
Somehow I missed the bold text in the question. If you absolutely need it to be a function, this kind of fits the definition (and is definitely intended as a joke):
function swap() {
return [arguments[1], arguments[0]];
}
var x = 1, y = 2;
console.log(`x = ${x}, y = ${y}`);
[x, y] = swap(x, y);
console.log(`x = ${x}, y = ${y}`);
To make swap(a,b) work as in C, you need references to the variables. It can be done lighter than in the above answer 1. Just
function swap(n, m) {
var temp = this[n];
this[n] = this[m];
this[m] = temp;
}
The this in this function is window, and call is swap('a', 'b'). Sure, you can avoid local variable temp with either logic or arithmetic (for ints).
I found this approach, which isn't too bad (at least for my purposes):
function swap( swap_name_a, swap_name_b )
{
eval
(
"var swap_temp="+swap_name_a+";"
+ swap_name_a+"="+swap_name_b+";"
+ swap_name_b+"=swap_temp;"
);
}
You are required to quote the arguments:
swap('a','b');
It seems to also work with more complex arguments:
swap('list[index1]','list[index2]');
Note: You will need to implement the swap() function within each scope that it will be used because it must have access to the named arguments. This goes against the "don't-repeat-yourself" principal, but in some circumstances it may be acceptable to copy-and-paste a bit of boilerplate code like this if it results in simplification of your algorithm logic.
By the way: The example from which I derived this returned the string from swap() and relied on the caller to forward the string to eval: eval(swap('a','b')). This solves the scope problem, but makes the swap operation more error prone -- and less attractive.
Be careful, that source also warned that this method could result in taunting.
Will time-traveling space-vampires steal your credit cards if you use eval()? You should decide that for yourself, but here's some help:
When is JavaScript's eval() not evil?
Why is using the JavaScript eval function a bad idea?
The biggest concern I see is that this might be relatively slow (depending on how the interpreter manages caching). If it is too slow for your purposes, then don't use it.
How to get the the variable name from within a function in this example:
// it should return A
var A = function(){ console.log(this.name); }
Is there something like this?
That function is anonymous; it has no name. You could, however, give it a name:
var A = function a() {};
Then its name is accessible via Function.name:
var A = function a() {};
A.name
> 'a'
I know this is an old thread, but still in search results. so just for reference:
a solution could simply be using the stacktrace.
var stack = new Error().stack;
use trim and split to get to the desired values.
No, there is nothing like that in Javascript. That function is anonymous, so it has no name, and what you want is ambiguous because the function could just as easily have any number of variables referencing it like:
var a, b, c, d;
a = b = function(){ console.log(this.name); };
c = b;
d = c;
a = b = 5;
// a and b no longer refer to the function, but c and d both do
What is it you are actually trying to accomplish? I'm sure there is another way to achieve it.
It is possible in recent versions of Chrome and Firefox as follows. I only recommend this for debugging purposes (e.g. javascript tracing in non-production)
var myNameInChrome = /.*Object\.(.*)\s\(/.exec(new Error().stack)[0];
var myNameInFF = new Error().stack.split("#")[0];