How to create variables that hold variables - javascript

I think this is a simple one, and it may even have been asked previously, but I don't know what keywords to use to do a search. I believe that variables are strings and can only be strings, so even my question is a poor one, but I want to figure out a good way to do some math.
We start with something simple, like:
var a=0, b=a+1
console.log(a,b) // yields 0,1
But I then want to be able to update a later in the code and have it automatically update b, so if later I set:
a=1
console.log(a,b) // now yields 1,2
The goal being the updated b without having to tell the code that b=a+1 a second time (or hundreds of times, as this is a lot of math I am playing with).

Instead of using a variable you could use an object with a getter and setter.
const obj = {
a: 0,
get b() { return this.a + 1 },
set b(value) { this.a = value - 1 },
};
console.log(obj);
obj.a = 10;
console.log(obj);
obj.b = 20;
console.log(obj);
If you never plan to set b, then you can omit the setter.

Create a separate function that updates both variables. Then, whenever you want to modify them, call the method instead of reassigning the variables manually, for example:
var a = 0,
b = a + 1;
const increment = () => {
a++;
b++;
};
increment();
increment();
console.log(a, b);

I would use a function for b instead and call it whenever is needed.
let a = 1;
const b = () => a + 1;
console.log(b()); // prints 2
a = 10;
console.log(b()); // prints 11

You can create a function to increment both the values.
const func= () => {
a++;
b++;
};
And then you can call the function each time you have to increment values. If you have to increment continuously for a fixed number of times then call the function inside a loop.

Related

How to extend Number in TypeScript by adding a function similar to ++

I would like to extend Number with a plusPlus2 function that will increment the number by 2.
The problem is that I don't know how to assign the result back to the number in the extension function. Something like:
Number.prototype.plusPlus2 = function() {
this = this + 2;
}
And the usage would be:
x = 1;
x.plusPlus2(); // expect x to be 3
Primitives (numbers, strings, booleans) are immutable in javascript.
So anytime you change a primitive, you need to assign it to another variable (or even reassign it to itself).
That being said, you cannot do what you propose, you need to return a new value, containing the value you want, let's say:
Number.prototype.plusplus2 = function() {
return this + 2;
}
And then reassign it:
let x = 5;
x = x.plusplus2();
Then, you may be wondering: how x++ works?
And the answer is, x++ is a syntax sugar for x = x + 1, meaning that, in fact, you are not changing x, but instead, adding 1 to x and reassigning it to itself.
You cannot. That has various reasons:
1) this is read only, as you don't expect it to change during the execution of a method.
2) What you access with this is a Number object that wraps the primitive number. It gets thrown away after the call. So even if you could change the internal value property containing the number, the value of x won't change.
Number.prototype.example = function() { this.stuff = "you see" };
let x = 1; // primitive
x.example(); // wrapped object
// wrapped object gets thrown away
console.log(x.stuff); // undefined, another wrapped object
3) Numbers are immutable and primitive. You can write a new number into x, but you can't turn all 1s into 3s.
You could create a new number, but then you have the problem that you have to write that number into x.
Number.prototype.plus2 = function() { return this + 2 };
let x = 1;
x = x.plus2();
Number.prototype.plus2 = function() {
return this + 2
}
let a = 2
console.log(a.plus2())

Modifying variables that are passed by reference in Javascript

I was watching a JavaScript talk, and the tutor said that if we pass a property of an object in a function it will actually change the real value, because we will be passing the variable by reference. Here is the slide:
but when I tried to practice the concept, that wasn't the case. Here is my code:
var obj = {val: 5};
function changeVal(x) {
x = x+5;
return x;
}
console.log(obj.val) // 5
console.log(changeVal(obj.val)) // 10
console.log(obj.val) // 5
I was expecting obj.val to change to 10.
Please tell me what's wrong here, and correct me if I am wrong. Thanks
You are passing not the object, but the primitive type. So when you pass the val of the obj, it is a number and is a primitive type.It copies the val and passes the copy to the object.
If you pass like this, it will work
var obj = {val: 5};
function changeVal( param ) {
param.val = param.val + 5;
return param.val ;
}
console.log(obj.val) // 5
console.log(changeVal(obj)) // 10
console.log(obj.val) // 10
You are not actually passing an object, just passing the value of property(val).
If you will pass obj in changeVal(), then it will actually change the value of the property of passed object.
For that you need to do like:
var obj = {val: 5};
function changeVal(x)
{
x = x+5;
return x;
}
console.log(obj.val); // 5
changeVal(obj); // Need to pass object instead of value of the property's value
console.log(obj.val); // 10
Primitive types (string, integer, boolean, etc...) are immutable, which means if you change one of the values inside a function, the callee (scope which calls your function) will not see the change.
function doSomething(a) {
a = a + 1;
}
var value = 2;
console.log(value); // result: 2
doSomething(value);
console.log(value); // result: 2
Pass-by-reference only works for objects. Like this:
function doSomething(obj) {
obj.attribute = obj.attribute + 1;
}
var myObject = {attribute: 2};
console.log(myObject.attribute); // result: 2
doSomething(myObject);
console.log(myObject.attribute); // result: 3
More reading about Javascript types:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
Say for instance you have an Iphone . Now lets say a manufacturing company calls you and asks to borrow your Iphone for a reference just so they can design an Iphone that is similar and sell it to customers . Your original Iphone still exists and is never gone , but every now and then the factory needs to use it for a reference , think of your function as the factory that just make a copy of obj.
//Original data
var obj = {val: 5};
Once your function returns something , it technically becomes a value
Example :
return 3; is a value of 3
so
function changeVal(x) {
x = x+5;
return x;
}
is a new value of x which in this case would be x + 5;
x is a copy of whatever you pass into the function .
Hope this helps.

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.

using key value pair of same object inside itself with 'this' in javascript

Let's say I have two objects like
var a = {
b: 1,
c: this.b
};
And
var funcObj = {
b : function() {
return 1;
},
c: function() {
console.log(return this.b())
}
}
On logging these two like
console.log(a.c)//results undefined
console.log(funcObj.c()) //results 1
Why can't the first function use the this property but the second one can?
I am really confused.
The answer depends on what this refers to in each context. In JavaScript, this is bound to whatever object was on the left of the dot (.) when the current function was called. If we're not in a function, things get a little hairier -- this is either the global window object or undefined, depending on the environment.
In your first example, the value of this is dependent on the surrounding context. As JavaScript builds your object a, it evaluates this.b. Whatever object this is currently bound to has no b property, so the c property is set to undefined.
In your second example, when you call funcObj.c() the this in the function gets bound to funcObj. So, when you ask for the b property, you get the b you defined above. The fact that funcObj.b is a function is actually irrelevant. The following would work just as well:
var funcObj = {
b : 1,
c: function() {
console.log(return this.b)
}
}
You cannot refer to other properties in the declaration as part of a Javascript literal declaration. So, in your Javascript literal declaration:
var a = {
b: 1,
c: this.b
};
this is not set to what you want and a has not yet been initialized yet so you can't refer to it either. There is simply no way to reach the other properties at the time of the literal declaration. This is a limitation of the current specification for Javascript. You could do this instead:
var a = {
b: 1
};
a.c = a.b;
because a is fully formed at that point so you can then reference other properties in it.
Or, in modern browsers, you could even use a getter to get the "live" version of b like this (which isn't exactly the same functionality as you were asking for since it's a "live" version of b that will track it's value), but shows you another possibility:
var a = {
b: 1,
get c() {
return b;
}
};
console.log(a.c); //results 1
In your second example:
var funcObj = {
b : function() {
return 1;
},
c: function() {
console.log(return this.b())
}
}
console.log(funcObj.c()) //results 1
You are calling funcObj.c() and that will set the value of this inside of c to funcObj so thus you can reference other properties via this.
The main difference here is that this is not set to the object inside of Javascript literal definition (your first example), but this is set to the object when you invoke a method as in funcObj.c().
I know this post is a bit old, but I came across it while trying to figure out how to solve a similar issue.
I was wanting to do something like:
const x = {
a: 12,
b: a + 1
}
console.log(x) //results undefined
(That's extremely simplified compared to what I was actually doing, but the principle is the same.)
My solution was to first create a function that would build the object I wanted, then pass in the primary value I was trying to act on (in this example, the value in 'a'):
function buildObj (val) {
const response = {
a: val,
b: val + 1
};
return response;
}
And then:
const x = buildObj(12)
console.log(x) // results { a: 12, b: 13 }
Once x has been initialized, any subsequent attempt to access
x.a
or
x.b
will return the values stored therein.
If a future searcher comes across this question because they're wanting to take an action on a value stored in a nested key within the same object, hopefully this will help.

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