In JavaScript, is there a way to get closure parameters - javascript

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());

Related

passing variables across functions on javascript

I'm trying to pass variables across functions,
something like
function one() {
var x = 1
}
function two() {
var y = x + 1;
}
alert(y);
Is there a way to do it?
edit:Thanks everyone for being so helpful, but maybe I should have been more specific with my question.
You current way has x and y in the scope of the function, which means the other function doesnt know it exists. Also, its good practice to name functions according to what they do. 3 straightforward ways to do this.
Global
Params
Inline
Set two variables outside of the functions scope that any function can reach.
var x, y;
function assignOne() {
x = 1;
}
function addOne() {
y = x + 1;
}
assignOne();
addOne();
console.log(y);
Pass in a parameter to to the function and return values.
function one() {
return 1;
}
function addOneTo(x) {
return x + 1;
}
const y = addOneTo(one());
console.log(y);
Perform functions inline
var x = null;
function one() {
x = 1;
}
function two() {
return x + 1;
}
one();
const y = two();
console.log(y);
You will need to hoist the scope, by extracting the variable declaration to outside of the functions. That is to say, define x and y outside of the functions. Note that you can still update their values from within the functions. However, don't forget that you'll actually need to invoke both functions as well!
This can be seen in the following:
var x, y;
function one() {
x = 1;
}
function two() {
y = x + 1;
}
one();
two();
console.log(y);
If you really want to get variable declared in one method, return it
function one(){
var x = 1;
return x;
}
function two() {
var x = one();
var y = x + 1;
return y;
}
alert(two());
Seems like you want to have shared state between both functions instead of passing arguments. So, an object oriented pattern seems to be appropriate.
class Thing {
constructor() {
this.x = 1;
}
one() {
return this.x;
}
two() {
return this.x + 1;
}
}
const t = new Thing();
console.log(t.one());
console.log(t.two());
If you want to share variables between functions but don't want to declare them in global scope, you can use a closure like this:
(function() {
var x, y;
function one() {
var x = 1
}
function two() {
var y = x + 1;
}
one();
two();
alert(y);
})();

Unable to access changed variable value inside nested functions

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]).

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.

javascript closures and prototypes

I thought I have understood the idee of closures, but the following code
behaves surprisingly for me:
function A(x)
{
this.getX1 = function () { return x; }
A.prototype.getX2 = function () { return x; }
}
var a1 = new A(1);
var a2 = new A(2);
console.log ('a1.getX1()=%d', a1.getX1 ()); // 1
console.log ('a2.getX1()=%d', a2.getX1 ()); // 2
console.log ('a1.getX2()=%d', a1.getX2 ()); // 2 ???
console.log ('a2.getX2()=%d', a2.getX2 ()); // 2
I could understand if prototype methods behave differently from
instance methods, but this looks like x has become a static variable.
Changing the order of calls does not change results.
When you change the prototype you're changing the function for all instances of the given class, including those that already exist.
Therefore when you call...
A.prototype.getX2 = function () { return x; }
You're setting that for the existing a1 instance of A. So effectively you're ending up with the following pseudo code:
<all instances of A>.getX2 = function () {
return <latest value of x passed to A constructor>;
}
The static member here is A.prototype.getX2. The second call to A.prototype.getX2 = function () { return x; } (due to var a2 = new A(2);) replaces the first one. To understand it you can reverse the order of instantiations:
var a2 = new A(2);
var a1 = new A(1);
Then you'll have:
a1.getX1()=1
a2.getX1()=2
a1.getX2()=1
a2.getX2()=1
You're defining getX2 twice, each time you create a new A. The result for that function will always be the last X. Considering rewriting your code like this:
function A(x) {
this.x = x;
this.getX1 = function() {
return this.x;
}
}
A.prototype.getX2 = function() {
return this.x;
}
var a1 = new A(1);
var a2 = new A(2);
console.log('a1.getX1()=%d', a1.getX1()); // 1
console.log('a2.getX1()=%d', a2.getX1()); // 2
console.log('a1.getX2()=%d', a1.getX2()); // 1
console.log('a2.getX2()=%d', a2.getX2()); // 2​​​
This way, you only define getX2 once and it works as expected.
You have written
function A(x)
{
this.getX1 = function () { return x; }
A.prototype.getX2 = function () { return x; }
}
This constructor overwrites A.prototype.getX2 each time.
So first
var a1 = new A(1); // This invokes A and adds a function `getX2` to the prototype of `A`which returns `x` that is `1`
var a2 = new A(2); // This invokes A and overwrites the function `getX2` in the prototype of `A` with a function which returns `x` that is `2` now.
So it should be like this
function A(x)
{
this.getX1 = function () { return x; }
}
A.prototype.getX2 = function () { return this.getX1(); }

How can I make var a = add(2)(3); //5 work?

I want to make this syntax possible:
var a = add(2)(3); //5
based on what I read at http://dmitry.baranovskiy.com/post/31797647
I've got no clue how to make it possible.
You need add to be a function that takes an argument and returns a function that takes an argument that adds the argument to add and itself.
var add = function(x) {
return function(y) { return x + y; };
}
function add(x) {
return function(y) {
return x + y;
};
}
Ah, the beauty of JavaScript
This syntax is pretty neat as well
function add(x) {
return function(y) {
if (typeof y !== 'undefined') {
x = x + y;
return arguments.callee;
} else {
return x;
}
};
}
add(1)(2)(3)(); //6
add(1)(1)(1)(1)(1)(1)(); //6
It's about JS curring and a little strict with valueOf:
function add(n){
var addNext = function(x) {
return add(n + x);
};
addNext.valueOf = function() {
return n;
};
return addNext;
}
console.log(add(1)(2)(3)==6);//true
console.log(add(1)(2)(3)(4)==10);//true
It works like a charm with an unlimited adding chain!!
function add(x){
return function(y){
return x+y
}
}
First-class functions and closures do the job.
function add(n) {
sum = n;
const proxy = new Proxy(function a () {}, {
get (obj, key) {
return () => sum;
},
apply (receiver, ...args) {
sum += args[1][0];
return proxy;
},
});
return proxy
}
Works for everything and doesn't need the final () at the end of the function like some other solutions.
console.log(add(1)(2)(3)(10)); // 16
console.log(add(10)(10)); // 20
try this will help you in two ways add(2)(3) and add(2,3)
1.)
function add(a){ return function (b){return a+b;} }
add(2)(3) // 5
2.)
function add(a,b){
var ddd = function (b){return a+b;};
if(typeof b =='undefined'){
return ddd;
}else{
return ddd(b);
}
}
add(2)(3) // 5
add(2,3) // 5
ES6 syntax makes this nice and simple:
const add = (a, b) => a + b;
console.log(add(2, 5));
// output: 7
const add2 = a => b => a + b;
console.log(add2(2)(5));
// output: 7
Arrow functions undoubtedly make it pretty simple to get the required result:
const Sum = a => b => b ? Sum( a + b ) : a;
console.log(Sum(3)(4)(2)(5)()); //14
console.log(Sum(3)(4)(1)()); //8
This is a generalized solution which will solve add(2,3)(), add(2)(3)() or any combination like add(2,1,3)(1)(1)(2,3)(4)(4,1,1)(). Please note that few security checks are not done and it can be optimized further.
function add() {
var total = 0;
function sum(){
if( arguments.length ){
var arr = Array.prototype.slice.call(arguments).sort();
total = total + arrayAdder(arr);
return sum;
}
else{
return total;
}
}
if(arguments.length) {
var arr1 = Array.prototype.slice.call(arguments).sort();
var mytotal = arrayAdder(arr1);
return sum(mytotal);
}else{
return sum();
}
function arrayAdder(arr){
var x = 0;
for (var i = 0; i < arr.length; i++) {
x = x + arr[i];
};
return x;
}
}
add(2,3)(1)(1)(1,2,3)();
This will handle both
add(2,3) // 5
or
add(2)(3) // 5
This is an ES6 curry example...
const add = (a, b) => (b || b === 0) ? a + b : (b) => a + b;
This is concept of currying in JS.
Solution for your question is:
function add(a) {
return function(b) {
return a + b;
};
}
This can be also achieved using arrow function:
let add = a => b => a + b;
solution for add(1)(2)(5)(4)........(n)(); Using Recursion
function add(a) {
return function(b){
return b ? add(a + b) : a;
}
}
Using ES6 Arrow function Syntax:
let add = a => b => b ? add(a + b) : a;
in addition to what's already said, here's a solution with generic currying (based on http://github.com/sstephenson/prototype/blob/master/src/lang/function.js#L180)
Function.prototype.curry = function() {
if (!arguments.length) return this;
var __method = this, args = [].slice.call(arguments, 0);
return function() {
return __method.apply(this, [].concat(
[].slice.call(args, 0),
[].slice.call(arguments, 0)));
}
}
add = function(x) {
return (function (x, y) { return x + y }).curry(x)
}
console.log(add(2)(3))
Concept of CLOSURES can be used in this case.
The function "add" returns another function. The function being returned can access the variable in the parent scope (in this case variable a).
function add(a){
return function(b){
console.log(a + b);
}
}
add(2)(3);
Here is a link to understand closures http://www.w3schools.com/js/js_function_closures.asp
const add = a => b => b ? add(a+b) : a;
console.log(add(1)(2)(3)());
Or (`${a} ${b}`) for strings.
With ES6 spread ... operator and .reduce function. With that variant you will get chaining syntax but last call () is required here because function is always returned:
function add(...args) {
if (!args.length) return 0;
const result = args.reduce((accumulator, value) => accumulator + value, 0);
const sum = (...innerArgs) => {
if (innerArgs.length === 0) return result;
return add(...args, ...innerArgs);
};
return sum;
}
// it's just for fiddle output
document.getElementById('output').innerHTML = `
<br><br>add() === 0: ${add() === 0 ? 'true' : 'false, res=' + add()}
<br><br>add(1)(2)() === 3: ${add(1)(2)() === 3 ? 'true' : 'false, res=' + add(1)(2)()}
<br><br>add(1,2)() === 3: ${add(1,2)() === 3 ? 'true' : 'false, res=' + add(1,2)()}
<br><br>add(1)(1,1)() === 3: ${add(1)(1,1)() === 3 ? 'true' : 'false, res=' + add(1)(1,1)()}
<br><br>add(2,3)(1)(1)(1,2,3)() === 13: ${add(2,3)(1)(1)(1,2,3)() === 13 ? 'true' : 'false, res=' + add(2,3)(1)(1)(1,2,3)()}
`;
<div id='output'></div>
can try this also:
let sum = a => b => b ? sum(a + b) :a
console.log(sum(10)(20)(1)(32)()) //63
const sum = function (...a) {
const getSum = d => {
return d.reduce((i,j)=> i+j, 0);
};
a = getSum(a);
return function (...b) {
if (b.length) {
return sum(a + getSum(b));
}
return a;
}
};
console.log(sum(1)(2)(3)(4,5)(6)(8)())
function add(a, b){
return a && b ? a+b : function(c){return a+c;}
}
console.log(add(2, 3));
console.log(add(2)(3));
This question has motivated so many answers already that my "two pennies worth" will surely not spoil things.
I was amazed by the multitude of approaches and variations that I tried to put "my favourite" features, i. e. the ones that I would like to find in such a currying function together, using some ES6 notation:
const add=(...n)=>{
const vsum=(a,c)=>a+c;
n=n.reduce(vsum,0);
const fn=(...x)=>add(n+x.reduce(vsum,0));
fn.toString=()=>n;
return fn;
}
let w=add(2,1); // = 3
console.log(w()) // 3
console.log(w); // 3
console.log(w(6)(2,3)(4)); // 18
console.log(w(5,3)); // 11
console.log(add(2)-1); // 1
console.log(add()); // 0
console.log(add(5,7,9)(w)); // 24
.as-console-wrapper {max-height:100% !important; top:0%}
Basically, nothing in this recursively programmed function is new. But it does work with all possible combinations of arguments mentioned in any of the answers above and won't need an "empty arguments list" at the end.
You can use as many arguments in as many currying levels you want and the result will be another function that can be reused for the same purpose. I used a little "trick" to also get a numeric value "at the same time": I redefined the .toString() function of the inner function fn! This method will be called by Javascript whenever the function is used without an arguments list and "some value is expected". Technically it is a "hack" as it will not return a string but a number, but it will work in a way that is in most cases the "desired" way. Give it a spin!
Simple Recursion Solution for following use cases
add(); // 0
add(1)(2)(); //3
add(1)(2)(3)(); //6
function add(v1, sum = 0) {
if (!v1) return sum;
sum += v1
return (v2) => add(v2, sum);
}
function add() {
var sum = 0;
function add() {
for (var i=0; i<arguments.length; i++) {
sum += Number(arguments[i]);
}
return add;
}
add.valueOf = function valueOf(){
return parseInt(sum);
};
return add.apply(null,arguments);
}
// ...
console.log(add() + 0); // 0
console.log(add(1) + 0);/* // 1
console.log(add(1,2) + 0); // 3
function A(a){
return function B(b){
return a+b;
}
}
I found a nice explanation for this type of method. It is known as Syntax of Closures
please refer this link
Syntax of Closures
Simply we can write a function like this
function sum(x){
return function(y){
return function(z){
return x+y+z;
}
}
}
sum(2)(3)(4)//Output->9
Don't be complicated.
var add = (a)=>(b)=> b ? add(a+b) : a;
console.log(add(2)(3)()); // Output:5
it will work in the latest javascript (ES6), this is a recursion function.
Here we use concept of closure where all the functions called inside main function iter refer and udpate x as they have closure over it. no matter how long the loop goes , till last function , have access to x.
function iter(x){
return function innfunc(y){
//if y is not undefined
if(y){
//closure over ancestor's x
x = y+x;
return innfunc;
}
else{
//closure over ancestor's x
return x;
}
}
}
iter(2)(3)(4)() //9
iter(1)(3)(4)(5)() //13
let multi = (a)=>{
return (b)=>{
return (c)=>{
return a*b*c
}
}
}
multi (2)(3)(4) //24
let multi = (a)=> (b)=> (c)=> a*b*c;
multi (2)(3)(4) //24
we can do this work using closure.
function add(param1){
return function add1(param2){
return param2 = param1 + param2;
}
}
console.log(add(2)(3));//5
I came up with nice solution with closure, inner function have access to parent function's parameter access and store in its lexical scope, when ever we execute it, will get answer
const Sum = function (a) {
return function (b) {
return b ? Sum(a + b) : a;
}
};
Sum(1)(2)(3)(4)(5)(6)(7)() // result is 28
Sum(3)(4)(5)() // result is 12
Sum(12)(10)(20) // result is 42
enter image description here
You should go in for currying to call the function in the above format.
Ideally, a function which adds two numbers will be like,
let sum = function(a, b) {
return a + b;
}
The same function can be transformed as,
let sum = function(a) {
return function(b) {
return a+b;
}
}
console.log(sum(2)(3));
Let us understand how this works.
When you invoke sum(2), it returns
function(b) {
return 2 + b;
}
when the returned function is further invoked with 3, b takes the value 3. The result 5 is returned.
More Detailed Explanation:
let sum = function(a) {
return function(b) {
return a + b;
}
}
let func1 = sum(2);
console.log(func1);
let func2 = func1(3)
console.log(func2);
//the same result can be obtained in a single line
let func3 = sum(2)(3);
console.log(func3);
//try comparing the three functions and you will get more clarity.
This is a short solution:
const add = a => b => {
if(!b) return a;
return add(a + b);
}
add(1)(2)(3)() // 6
add(1)(2)(3)(4)(5)() // 15

Categories

Resources