Replace a variable in a function with the value in javascript - javascript

I am looking for a way to replace a variable in a function with its actual value. I am going to convert this function into a string and send via a HTTP request and thus need to convert the variables inside the function with their values.
let x = Math.random();
let funcString = function () {
let y = x + 10;
return y;
}.toString();
// Send funcString as a parameter
For eg. in the above code if I send funcString as it is, whoever receiving it will have no idea what is the value of x.
Since I am ultimately sending a string I would like to send
"function () {let y = 0.53 + 10; return y;}" (assuming
Math.random() produced 0.53 at runtime).
Is there any way to do this?
I am doing this in a nodejs project so a npm module would be fine by me too.

Well if you are returning this function as a string, just use String#replace() method to replace x occurrence with its value.
This is how you should use it:
funcString.replace('x', x)
Demo:
let x = Math.random();
let funcString = function () {
let y = x + 10;
return y;
}.toString();
console.log(funcString.replace('x', x));
Edit:
If your variable has many occurrences and can be part of other variables just use a regex with replace method.
funcString.replace(/\bx\b/g, x)
Demo:
let x = Math.random();
let funcString = function () {
let y = x + 10;
let fix ='true';
let z = x * 2;
return y;
}.toString();
console.log(funcString.replace(/\bx\b/g, x));

use replace with regex, g will search all x-es
let x = Math.random();
let funcString = function () {
let y = x + 10;
let a = x + 10;
let b = x + 10;
return y;
}.toString().replace(/x/g, x);
console.log(funcString);

Related

I couldnt call a value from other function

The js code has 3 functions. I want to call values from the 2 functions and execute them in the 3rd function.
function first() {
var x = 2
var y = 3
var z = x * y
}
first()
function second() {
first();
var z;
var a = z - 1
}
second()
function third() {
first();
second();
var a
var z
var ans = a * z
console.log(ans);
document.getElementById("ans_html").innerHTML = precision(ans);
}
third()
<div id="ans_html"></div>
The expected outcome was 30.
But the output was "NaN".
In most languages, including JS, variables have "scope" (mdn). If you want to share data between function's, you can either
1) return values (mdn),
function first() {
var x = 2
var y = 3
return x * y;
}
function second() {
let z = first();
return z - 1
}
function third() {
let z = first();
let a = second();
var ans = a * z
console.log(ans);
}
third();
2), less conventionally, modify a param obj since they're are passed by ref.
let func = param => {
param.x = 3;
param.y = 4;
};
let a = {};
func(a);
console.log(a);
You will need to either create global variables which is considered a bad practice, or pass values around as parameters.
Global variables:
var a
var x
var y
var z
function first() {
x = 2
y = 3
z = x * y
}
function second() {
a = z - 1
}
function third() {
first()
second()
let ans = a * z
console.log(ans);
}
Passing Parameters:
function first(x, y) {
return x * y
}
function second(z) {
return z - 1
}
function third() {
let x = 2
let y = 3
let z = first(x, y)
let a = second(z)
let ans = a * z
console.log(ans);
}
Judging based on your code, you likely should take a look into how JavaScript scopes variables based on using the keyword var vs let. I hope this helps!
You have two major issues:
Your variables a and z are not global variables. They are defined within the function itself so you cannot access those variables outside of that scope (see this)
I would not fix your code to adhere to the first issue. You don't need global variables here, you just need to return the result so you can call your functions later. In the long run, I would assume you want to add arguments to your functions, but the below is an example of how to do what you're trying to accomplish by simply returning the result in your functions.
NOTE I don't know if you have a custom precision function or what. So, I added an empty function that just returns the input. You can probably remove this.
function precision(num) {
// Insert whatever is in your precision function here...
return num;
}
function first() {
var x = 2
var y = 3
var z = x * y
return z;
}
function second() {
var z = first();
var a = z - 1
return a;
}
function third() {
var a = second();
var z = first();
var ans = a * z
console.log(ans);
document.getElementById("ans_html").innerHTML = precision(ans);
}
third()
<div id="ans_html"></div>
This is not the best design pattern, but if you want to achieve this in this way, the code is going to look like the one below. You need to return the result of the function in order to get it in another function and use it.
function first() {
var x = 2
var y = 3
return x * y
}
function second() {
var z = first()
return z - 1
}
function third() {
var a = first()
var z = second()
var ans = a * z
console.log(ans);
// document.getElementById("ans_html").innerHTML = precision(ans);
}
third()
<div id="ans_html"></div>

Array(push - object) not working as expected

I'm having issues with pushing object into an array.
I set an object with values and push them to the array. I then change some of the values of the object and push the object into the array again.
However, on inspection, both objects pushed into the array are identical, both object's values are identical to the last object that was pushed into the array.
let ProductPosition = function (x, y) {
this.x = x;
this.y = y;
}
let PalletType = (function () {
function PalletType() {
this.PatternType = '';
this.ProductWidth = 0;
this.PalletWidth = 0;
this.ProductPositions = [];
}
});
function getPalletPositions(pallet, pattern) {
pal.ProductPositions = [];
let posn = new ProductPosition();
switch (pattern) {
case '1U1':
posn = [];
posn.y = pal.PalletWidth / 2;
posn.angle = 0;
posn.apprDir = 0;
pallet.ProductPositions.push(posn);
break;
case '2U1':
posn = [];
posn.y = pal.PalletWidth / 2 + pal.ProductWidth / 2;
console.log('y pos 0 ' + posn.y);
pal.ProductPositions.push(posn);//first push
posn.y = pal.PalletWidth / 2 - pal.ProductWidth / 2;
console.log('y pos 1 ' + posn.y);
pallet.ProductPositions.push(posn);//first push
break;
}
}
let pal = new PalletType();
pal.PalletWidth = 1165;
pal.ProductWidth = 400
let pat = '2U1';
getPalletPositions(pal, pat);
pal.ProductPositions.forEach(function (pos) {
console.log("pos.y:" + pos.y);
});
Actual output:
y pos 0 782.5 <-value of y of first push
y pos 1 382.5 <-value of y of second push
pos.y:382.5 <-should be 782.5
pos.y:382.5
I'd expect:
y pos 0 782.5 <-value of y of first push
y pos 1 382.5 <-value of y of second push
pos.y:782.5
pos.y:382.5
I'm totally baffled and tried a few things, but to no avail.
You were mutating that object you can use spread operator or Object.assign
Check below
let ProductPosition = function (x, y) {
this.x = x;
this.y = y;
}
let PalletType = (function () {
function PalletType() {
this.PatternType = '';
this.ProductWidth = 0;
this.PalletWidth = 0;
this.ProductPositions = [];
}
});
function getPalletPositions(pallet, pattern) {
pal.ProductPositions = [];
let posn = new ProductPosition();
debugger;
switch (pattern) {
case '1U1':
posn = [];
posn.y = pal.PalletWidth / 2;
posn.angle = 0;
posn.apprDir = 0;
pallet.ProductPositions.push(posn);
break;
case '2U1':
posn = [];
posn.y = pal.PalletWidth / 2 + pal.ProductWidth / 2;
console.log('y pos 0 ' + posn.y);
pal.ProductPositions.push({...posn});//first push
posn.y = pal.PalletWidth / 2 - pal.ProductWidth / 2;
console.log('y pos 1 ' + posn.y);
pallet.ProductPositions.push({...posn});//first push
break;
}
}
let pal = new PalletType();
pal.PalletWidth = 1165;
pal.ProductWidth = 400
let pat = '2U1';
getPalletPositions(pal, pat);
pal.ProductPositions.forEach(function (pos) {
console.log("pos.y:" + pos.y);
});
That's because "posn" is an Object, so you are actually pushing a reference to this object rather than a primitive value.
You could, for example, copy the object:
pallet.ProductPositions.push({...posn});
The Spread operator will create a shallow copy.
If you need a deep copy use the following:
pallet.ProductPositions.push(JSON.Parse(JSON.Stringify(posn)));
Pay attention that the JSON method is not able to copy functions.
You're trying to push the same object 2 times in the same array. The first time with some value and next time, you're modifying the value in the same object and pushing in the array. So in total the same object reference is getting modified. As a result, the array has same object added 2 times.
Another way is, you can use slice operator on your array to create new instance of the array and then do the second push. OR create 2 different variables and then push it.
Thank you all for your prompt responses, it is very much appreciated.
Solved by using:
let x;
let y;
let angle;
let apprDir;
and assigning these directly. Then:
pallet.ProductPositions.push(new ProductPosition(x, y, angle, apprDir));
Works a treat and simplified the code.

How can I bind a local variable to another local variable when it changes

I'm working on an ionic 2 project which uses angular 2.
I just have this in mind if there's a way I can create a variable to bind to
another variable(s).
Let's say,
let x = 1;
let y = x;
where y will have the exact value of x even when it changes.
And if it does work, can I also do this?
let x = 1;
let y = 1;
let z = x + 1;
I'd like to know if this is possible or not.
Just had this in mind. Thanks and cheers!
In Angular components and providers this is solved with property accessors:
class SomeService {
x = 1;
get y() {
return this.x;
}
get z() {
return this.x + 1;
}
}
It's not possible to pass scalar value by reference (and there are usually no reasons to do that in Angular).
Javascript does not allow passing reference of the primitive types. So you can achieve this by wrapping them in an object.
let x = {
value: 1,
get z() { return this.value + 1}
}
let y = x;
y.value = 10; // Now x.value is also 10

Variable hoisting examples [duplicate]

This question already has answers here:
Surprised that global variable has undefined value in JavaScript
(6 answers)
Closed 7 years ago.
Hi I have a snippet of code. I am confused about change of value x1 when I remove non-related part of same code. I searched about it and I came to know that it has to do with hoisting. But the value x1 is still unclear even with hoisting concept for me. Can someone please make me clear on this?
var x = 10;
function main() {
document.write("<br>x1 is " + x);
x = 20;
if (x > 0) {
var x = 30;
document.write("<br>x2 is " + x);
}
var x = 40;
var f = function(x) {
document.write("<br>x3 is " + x);
}
f(50);
}
main();
The output of this code is:
x1 is undefined
x2 is 30
x3 is 50
If I change this code to:
var x = 10;
function main() {
document.write("<br>x1 is " + x);
}
main();
The output is:
x1 is 10
So what is happening here is a common pitfall.
The simplest way to put this is. When you set var x = 30 inside your main function, you are actually redefining the scope that var x = 10 had for use inside this function. This has to do with how Javascript executes and scope.
By defining x inside the function, your scope for x has changed. Below is an example of what I mean and a version of your code that works
Example:
var test = 'test';
function run(){
console.log(test);
var test=1;
}
Your Code Updated:
var x = 10;
function main() {
console.log("<br>x1 is " + x);
x = 20;
if (x > 0) {
x = 30;
console.log("<br>x2 is " + x);
}
x = 40;
var f = function(x) { console.log("<br>x3 is " + x); }
f(50);
}
main();
Good question btw.
Since this is somewhat of a very interesting scope of how Javascript executes, consider the following code and its outputs to get the full idea
var test = 'test';
function run(){
console.log(test);
test=1;
console.log(test);
var test=2;
console.log(test);
}
console.log(test);
run();
console.log(test);
Very interesting to see how this reacts.
All variable and function declarations get "hoisted" or moved to the top of their scope. The undefined value for x is caused because the var x statement gets moved up to the top of main however the assignment = 30 does not.
So, your code will read more like this:
var x = 10; // x is 10
function main() {
var x; // x declaration is "hoisted"
document.write("<br>x1 is" + x); // x1 is undefined
x = 20; // x is 20
if (x > 0) {
x = 30; // x is 30
document.write("<br>x2 is" + x);// x2 is 30
}
x = 40; // x is 40
var f = function(x) { // x is 50
document.write("<br>x3 is" + x);// x3 is 50
}
f(50);
}
main();
You can read more about Hoisting here: JavaScript Scoping and Hoisting

How do I convert Dynamic Javascript to Text?

I have some code (whatever is inside the body of the jsToBeConverted function below) that I want to be able to convert it into text so that the user can copy it and then paste it inside a <script> element on their site in order to have it executed.
someElement.onclick = function ()
{
var textForUserToCopy = (function ()
{
x = document.getElementById('someInput').value;
var jsToBeConverted = function ()
{
var y = x + 6;
var z = function (a)
{
return (a + 5);
};
window.d = z(y);
};
var jsToExecute = "(" + jsToBeConverted + ")();"
return jsToExecute;
})();
};
However this would generate the following text :
"(function ()
{
var y = x + 6;
var z = function (a)
{
return (a + 5);
};
window.d = z(y);
})();"
But this isn't what I want. If the above is evaluated x will obviously be undefined.
What I want is for x to be replaced by its value at the time and then have the js converted into text. So if the value of x happened to be 123, this is what the generated text should look like :
"(function ()
{
var y = 6 + 6;
var z = function (a)
{
return (a + 5);
};
window.d = z(y);
})();"
If the above string is evaluated - window.d would be 17
Is the there some standard function/process for generating/converting dynamic code into text?
Thank you
You can simply concatenate.
e.g.:
"function (x) { return " + generated_value + " + x }";
For a more elegant looking solution, see string formatting:
JavaScript equivalent to printf/string.format

Categories