Unable to access changed variable value inside nested functions - javascript

I have a huge business logic to be executed in both of the below functions but I struck in one issue. I know its related to closure but how to solve I am not aware of. Can you through some light.
function func1() {
var x = false;
console.log('before going inside func '+x);
func2(x);
console.log('After coming outside => '+x);
//Instead of true its displaying false
}
function func2(x)
{
x = true;
console.log('inside func => '+ x);
}
func1();
My original problem is like below
function func1() {
var x = false;
var y =1;
var z=3;
func2(x,y,z);
console.log(x,y,z);
//INSTEAD OF true,10,30; its displaying false,1,3
}
function func2(x,y,z)
{
x = true;
y=10;
z=30;
}
func1();

The x parameter of func2 is completely distinct from the x variable in func1. When you do func2(x), the value of x is passed to func2, not some kind of reference to the variable. (Some languages do that; JavaScript does not.)
To return information out of a function, use return in the function, and use the function's return value where you call it:
function func1() {
var x = false;
console.log('before ' + x);
x = func2(x); // *** Note `x =`
console.log('after ' + x);
}
function func2(x) {
return true;
}
func1();
Perhaps a better example, using the value of x in func2:
function func1() {
var a = 1;
var b = 12;
console.log('a before: ' + a);
a = func2(a);
console.log('a after: ' + a);
console.log('b before: ' + b);
b = func2(b);
console.log('b after: ' + b);
}
function func2(x) {
return x * 2;
}
func1();
If you have complex information to return, return an object with properties for the complex information (or pass in an object, and have func2 fill in properties on it, it depends on the use case [and whether you're adhering to immutability paradigms]).

Related

How to write a function to evaluate this expression? [duplicate]

A friend of mine challenged me to write a function that works with both of these scenarios
add(2,4) // 6
add(2)(4) // 6
My instinct was the write an add() function that returns itself but I'm not sure I'm heading in the right direction. This failed.
function add(num1, num2){
if (num1 && num2){
return num1 + num2;
} else {
return this;
}
}
alert(add(1)(2));
So I started reading up on functions that return other functions or return themselves.
http://davidwalsh.name/javascript-functions
JavaScript: self-calling function returns a closure. What is it for?
JavaScript: self-calling function returns a closure. What is it for?
I am going to keep trying, but if someone out there has a slick solution, I'd love to see it!
I wrote a curried function whose valueOf() method and function context (this) are bound with the sum no matter how many arguments are passed each time.
/* add function */
let add = function add(...args) {
const sum = args.reduce((acc, val) => acc + val, this);
const chain = add.bind(sum);
chain.valueOf = () => sum;
return chain;
}.bind(0);
/* tests */
console.log('add(1, 2) = ' + add(1, 2));
console.log('add(1)(2) = ' + add(1)(2));
/* even cooler stuff */
console.log('add(1, 2)(3) = ' + add(1, 2)(3));
console.log('add(1, 2, 3)(4, 5)(6) = ' + add(1, 2, 3)(4, 5)(6));
/* retains expected state */
let add7 = add(7);
console.log('let add7 = add(7)');
console.log('add7(3) = ' + add7(3));
console.log('add7(8) = ' + add7(8));
The reason why both mechanisms are required is because the body of add() must use the called function's bound context in order to access the sum of the intermediate partial application, and the call site must use the valueOf() member (either implicitly or explicitly) in order to access the final sum.
There is an article on Dr.Dobs Journal about "Currying and Partial Functions in JavaScript" which describes exactly this problem.
One solution found in this article is:
// a curried add
// accepts partial list of arguments
function add(x, y) {
if (typeof y === "undefined") { // partial
return function (y) {
return x + y;
};
}
// full application
return x + y;
}
function add(num1, num2){
if (num1 && num2) {
return num1 + num2;
} else if (num1) {
return function(num2){return num1 + num2;};
}
return 0;
}
The concept that you're looking for is called currying and it has to do with function transformation and partial function application. This is useful for when you find yourself calling the same function over and over with mostly the same arguments.
An example of implementing add(2)(6) via currying would look something like this...
function add(x,y) {
if (typeof y === 'undefined') {
return function(y) {
return x + y;
}
}
}
add(2)(4); // => 6
Additionally, you could do something like this...
var add6 = add(6);
typeof add6; // => 'function'
add6(4); // => 10
var add = function(){
// the function was called with 2 arguments
if(arguments.length > 1)
arguments.callee.first_argument = arguments[0];
// if the first argument was initialized
if(arguments.callee.first_argument){
var result = arguments.callee.first_argument + arguments[arguments.length - 1];
arguments.callee.first_argument = 0;
return result;
}else{// if the function was called with one argument only then we need to memorize it and return the same function handler
arguments.callee.first_argument = arguments.callee.first_argument || arguments[0];
return arguments.callee;
}
}
console.log(add(2)(4));
console.log(add(2, 4));
An extended solution which depends on the environment:
function add(){
add.toString = function(){
var answer = 0;
for(i = 0; i < add.params.length; i++)
answer += add.params[i];
return answer;
};
add.params = add.params || [];
for(var i = 0; i < arguments.length; i++)
add.params.push(arguments[i])
return add;
}
console.log(add(2)(4)(6)(8))
console.log(add(2, 4, 6, 8));
We can use the concept of closures which is provided by Javascript.
Code snippet:
function add(a,b){
if(b !== undefined){
console.log(a + b);
return;
}
return function(b){
console.log(a + b);
}
}
add(2,3);
add(2)(3);
In general you need to have an agreement whether the function should return a function (for calling with more arguments) or the end result. Imagine the add function would have to work like this as well:
add(1, 2, 3)(4, 5) // -> 15
...then it becomes ambiguous, because you might want to call again:
add(1, 2, 3)(4, 5)(6) // -> 21
...and so add(1, 2, 3)(4, 5) should have returned a function, and not 15.
You could for instance agree that you have to call the function again, but without arguments, in order to get the numeric result:
function add(...args) {
if (args.length === 0) return 0;
let sum = args.reduce((a, b) => a+b, 0);
return (...args) => args.length ? add(sum, ...args) : sum;
}
console.log(add()); // 0
console.log(add(1,2,3)()); // 6
console.log(add(1,2,3)(4,5)()); // 15
console.log(add(1,2,3)(4,5)(6)()); // 21
One may think that he/she has to invoke the same function two times, but if you think deeply you will realize that the problem is pretty straight forward, you have to invoke the add function one time then you need to invoke what ever the add function returns.
function add(a){
return function(b){
return a+b;
}
}
console.log(add(20)(20));
//output: 40
you can return function as many as time you want. suppose for y = mx+c
const y= function (m){
return function(x){
return function (c){
return m*x+c
}
}
}
console.log(y(10)(5)(10));
//out put: 60

Return statements with currying techniques

While learning with FreeCodeCamp I'm faced with a question about currying.
The solution was this:
function add(x) {
// Add your code below this line
return function(y) {
return function(z) {
return x + y + z;
}
}
}
add(10)(20)(30);
However, I'm confused as to why the return statements here aren't terminating the execution of the function?
I was under the impression that as soon as you use a return statement, that line would be executed and everything beyond that would be ignored.
It ends only the own function. The returned function isn't called yet.
function add(x) {
return function(y) { // \
return function(z) { // |
return x + y + z; // | part of the returned function
}; // |
}; // /
}
add(10)(20)(30);
Yes using return does end the functions execution, but the returned value is a function itself, that then gets called directly, the next function gets executed, ended with returning another function, that then gets called directly again and produces the result.
add(10)(20)(30);
// evaluted to:
function(x) {
return function(y) {
return function(z) {
return x + y + z;
};
};
}(10)(20)(30)
// evaluated to:
function(y) { // x = 10 through closure
return function(z) {
return x + y + z;
};
}(20)(30);
// evaluated to
function(z) { // x = 10, y = 20 through closure
return x + y + z;
}(30)
// evaluated to
60
Each time it is returning a new function, its being executed.
You would be right if one function had multiple return statements, but in this case, there are multiple functions (each with their own return statement). Two of the functions just happen to return another function.

In JavaScript, is there a way to get closure parameters

I have two file:
//------------a.js--------------
function a(){
return '1'
}
var testCase = {
func(){
return a()
}
}
module.exports = testCase
//------------b.js--------------
var testCase = require('./a.js')
//Can I get closure parameters(function a) that not modify a.js?
Is there a way to get closure parameters In JavaScript? Thank You!
If you mean to return the list of parameters from a closure like get x and y from closure run(x, y) {} which is inside function walk() {} then the below code might help.
function walk() {
function run(x, y) {
return x + y;
}
return run;
}
var fun = walk();
fun.getParameters = function () {
var functionText = this.prototype.constructor.toString();
return functionText
.substring(functionText.indexOf('(') + 1, functionText.indexOf(')'))
.split(',')
.map(x => x.trim());
};
console.log(fun.getParameters());

Javascript - function with arguments as another function's argument

I'm trying to pass a function with two arguments as an argument to another function (sort of callbacks). I have one function that is unchangeble ("F"), and another that's a wrapper to the former one, and which I can code the way I like ("G"). I tried to simplify the code as much as possible, leaving just the important parts of it:
"use strict"
// this function can't be changed in any way
var F = function (a, b)
{
return new G(function (success, error)
{
var sum = a + b;
if (sum > 0)
{
// EXCEPTION: point of failure, since we can't reach G.success
success(sum);
}
else
{
// of course we'd fail here too
error(sum);
}
});
};
var G = function (f)
{
this.success = function (result)
{
console.log("The sum is positive: " + result);
}
this.error = function (result)
{
console.log("The sum is negative: " + result);
}
return f();
};
var result = F(10, 5);

javascript, can a variable be a value and also a function?

It is possible to code in javascript like the following:
var foo = function(n) { //magic codes };
var bar = foo(2);
bar + 2 // result: 4
bar(2) // result: 4
bar(2)(2) // result: 6
A variable can only hold one value. That value can be a function.
An object can have a toString() method which could be hacked to get close to what you are trying to do.
function myFactory(value) {
function myFunction(add) {
return myFactory(value + add);
}
myFunction.toString = function() {
return value;
};
return myFunction;
}
var bar = myFactory(2);
console.log(bar + 2);
console.log(bar(2));
console.log(bar(2)(2));
This is, of course, horrible.
Currying can be done in Javascript, by returning a function.
By default variables can either be values (literal, or results of functions), or function declarations.
function add(number) {
return function(number2) {
return number + number2;
}
}
console.log(add(5)(6));
There are ways to achieve what you described bar + 2, but that's unconventional, and in my opinion, you shouldn't use them in Javascript.
I got inspired by Quetin's answer and found the valueOf property
var foo = function(n) {
var fn = function(x) {
return foo(n + x);
};
fn.valueOf = function() {
return n;
};
return fn;
}
var bar = foo(2);
console.log(bar + 2 === 4, bar);
console.log(bar(2) === 4, bar(2));
console.log(bar(2)(2) === 6, bar(2)(2));
I admit the log results does come out strange but it works as intended.

Categories

Resources