how to make a function that makes functions? - javascript

ok so, it's 3am here and this stupid issue is keeping me up, bothering me all night long,
basically what i was trying to do is to make a function that takes an existing function as a parameter to return a constructor function, maybe this will be obvious reading my code
var f = function() {
return function(p) {
return document.createElement(p)
}
};
var x = f();
alert(x); //alerts function(p){ return document.createElement(p)}
var n = x("div"); //it creates div Element
alert(n); // alert [object HTMLDivElement]
the code above works just fine but i want to use variables instead of putting the createElement directly inside the constructor function, i want to pass it as a parameter to the function f like this
var f = function(dd) {
return function(p) {
return dd(p)
}
};
var x = f(document.createElement);
alert(x); //alerts function(p){ return dd(p)}
var n = x("div"); //doesn't createElement
alert(n); //doesn't alert
in addition to that , the last code outputs something weird in the console illegal invocation, I have no idea whats wrong wmy code, please help?

You have to bind the createElement method to the document object. Otherwise, you're calling a method, but it doesn't have the proper context.
var f = function(dd) {
return function(p) {
return dd(p)
}
};
var x = f(document.createElement.bind(document));
alert(x);
var n = x("div");
alert(n);
The arrow function version would be
var f = dd => p => dd(p);
var x = f(document.createElement.bind(document));
alert(x);
var n = x("div");
alert(n);

You have to bind the createElement method to the document
var x = f(document.createElement.bind(document));

Related

Confusing function in javascript functional programming

I'm new to functional programming and I'm trying to learn it in javascript. I found some examples and wrote my own snippet, but I don't understand WHY it works. There is a function called whatTheHeckIsThis. Can someone tell me what it is doing or what its purpose is? Note that when running this code, the output is true.
function boolFlipper(someFn){
return function whatTheHeckIsThis(x,y){
return !someFn(x,y);
};
}
var checkStrings = function(x, y){
return x === y;
}
var flipperTester = boolFlipper(checkStrings);
var str1 = "this string";
var str2 = "that string";
console.log(flipperTester(str1, str2));
My confusion is why can't I just do this instead:
function boolFlipper(someFn){
return !someFn(x,y);
}
a reference to whatTheHeckIsthis() will be returned and stored into flipperTester
After this, flipperTester can be used like a function.
You can use this language feature to abstract some code.
Simple example:
function addTen(x) { return x + 10 }
function multiplyByTen(x) { return x * 10 }
...
var doMath
// somewhere a user selected something
if (userInputSaysAdd) doMath = addTen
if (userInputSaysMultiply) doMath = multiplyByTen
// this will be the choosen function
doMath(someValue)
Your second version doesn't work for 2 reasons:
The purpose of boolFlipper is to return a new function, which you can assign to another variable and later call.
Your function doesn't have x and y parameters.
To solve #2 you could write:
function boolFlipper(someFn, x, y) {
return !someFn(x, y);
}
You would then have to call it like:
console.log(boolFlipper(checkStrings, str1, str2));
But you still couldn't do:
flipperTester = boolFlipper(checkStrings);
The original snippet returns a closure, which is bound in the environment where someFn is equal to the function passed as an argument to bookFlipper(). You can then assign this function to a variable, and call it with new arguments, that are assigned to x and y, and then the the function saved in someFn() is called, the return value is negated with !, and this is returned.
For more information about closures, see How do JavaScript closures work?
In JavaScript functions are objects, so you can return them. When you return a function you are getting a function object, so you can call it as any other function. For example:
function myFun() {
return function() {
console.log("test");
};
}
var functionInside = myFun();
/* This is like doing:
var functionInside = function() {
console.log("test");
};
*/
functionInside(); // This will execute the function.
Example with your code:
This variable:
var flipperTester = boolFlipper(checkStrings);
contains a function like this:
var flipperTester = function (x,y) {
return !someFn(x,y);
}
And this is something similar to
function flipperTester(x,y) {
return !someFn(x,y);
}
So when you do:
flipperTester(str1, str2)
You are executing that function. The variable "someFn" inside there is the function "checkStrings", because you passed it when you initialize flipperTester variable.
boolFlipper is, for our purposes here, a function decorator: it takes a function and modifies it to do something else. A more instructive example might be a logging function:
var alsoLogs = f => (...args) => {
var result = f(...args);
console.log(result);
return result;
};
// now we have a function that adds 2 numbers:
var add = function add(a, b) { return a + b; };
// and we want to also log the result
var addAndLog = alsoLogs(add); // addAndLog is a function, would be the whatTheHeckIsThis from your example
addAndLog(2, 3); // logs 5 to the console
If you don't understand all the ES6 syntax that's ok, just understand that alsoLogs take a function f and returns a function that does the exact same thing as f but also logs the result to the console.
Since we as programmers are lazy, we don't want to have to write functions to glue together other functions every time we want to do this, so we write a function to do it for us, compose.
So now we can just say something like:
var addAndLog = R.compose(console.log, add);
addAndLog(2, 3); // logs 5 to the console

Nested functions in closure not being called properly in Javascript

I am new to Javascript and learning about closures and nested scope.
The prompt asks for this:
Write a function that has three nested functions, each taking one number as an argument. The inner-most function should return the sum of all three numbers.
This is what I have come up:
var outMost = function (num1) {
var x = num1;
var innerMost = function (num2) {
var y = num2;
var innerInnerMost = function (num3) {
console.log(x + y + num3);
}
return innerInnerMost;
}
return innerMost;
}
var firstNum = outMost(1);
firstNum(2);
firstNum((3));
Please help me understand what I am doing wrong -- I have gone on numerous website to learn about closures and scope but nothing seems to explain it well. Thank you for the help.
When you call firstNum(2), you are not catching the return-value (which is a function). If I run your code in Node.js REPL, here is what it looks like:
> var firstNum = outMost(1);
undefined
> firstNum(2);
[Function]
> firstNum((3));
[Function]
Try this in the end instead:
var firstNum = outMost(1);
var secondNum = firstNum(2);
secondNum(3);
Here is what it looks like in Node.js REPL:
> var firstNum = outMost(1);
undefined
> var secondNum = firstNum(2);
undefined
> secondNum(3);
6
undefined
Please note that assignment evaluates to undefined. Also, since innerInnerMost doesn't return anything, there is an implicit return undefined in the end.
function firstFunc(x){
return function secondFunc(y){
return function thirdFunc(z){
console.log(x+y+z);
}
}
}
Calling:
var ff = firstFunc(1);
var sf = ff(2);
sf(3);
very easy look at this example
if you have this type
in ES6
let f = () => {
return () => {
console.log('First function called');
return () => {
console.log('Second function called');
}
}
}
you have two way to call every function, first of all, I want to call the First function
in this way f()() and then I want to call the Second function f()()().
First of all, you will be seeing in console
First function called
and then
Second function called
and another way you can use this technic
let f1 = f();
let f2 = f1();
you will be seeing
First function called
if you want to the second function call
let f1 = f();
let f2 = f1();
let f3 = f2();
and then you will be seeing
Second function called
if you want to change this code to ES5
var f = function() {
return function() {
console.log('First function');
return function(){
console.log('Second function');
}
}
}
two way of call
var f1 = f();
var f2 = f1();
var f3 = f2();
f()()();

Get the value of a variable and array outside a self-invoking function

I have a self invoking function in javascript and I have another function in the same file where I need the value of a variable that is inside the self-invoking function. How can I do that?
Edit: So I can get one variable, but how about more variables or an array?
And I also have a semicolon at the beggining, how to deal with it:
;(function() {
...
})();
You need to set it as part of the return. Depending upon your exact pattern it could go like
var app =(function(){
var x = 5;
function app() {
}
app.x = x;
return app;
})();
Simple define the variable not in the function but before:
var a = 1;
(function(){ /* do stuff and use a*/})();
function(){
// use a again
}
var x = (function(y) { return y + 2; })(2);
alert(x);
Works just like this:
function addTwo(y) { return y + 2; }
x = addTwo(2);
//Your self invoking func
(function(){
var getStuff = holdsStuff();
console.log(getStuff.a); //getStuff.b, getStuff.cArr etc;
})();
//func in same file that holds the vars that you need.
function holdsStuff(){
var a = 10;
var b = 15;
var cArr = [1,2,3,4,5];
return { a: a, b: b, cArr: cArr};
}

Does assigning a function to a variable in javascript run the function

I have three simple programs below with different outputs. I am a bit confused as to why I get a different output. What really happens when you assign a function to a variable? Does it not run unless you have parentheses (i.e. myfunction())? I'm also very confused as to how JavaScript allows the parenthesis behind a function as 'optional' when calling it. Can someone clear this up? I only know Java so this is all new territory for me.
// ------First--------------------------------
var x = 9;
function myfunction (){
x = 3;
}
var w = myfunction;
w();
console.log(x);
//output is 3
// ---------Second -----------------------------
var x = 9;
function myfunction (){
x = 3;
}
var w = myfunction;
console.log(x);
//output is 9
// ---------Third -----------------------------
var x = 9;
function myfunction (){
x = 3;
}
var w = myfunction();
console.log(x);
//output is 3
No, it does not. A reference to a function by name is simply a reference to a value, like any other value. Without the () operator, it's not a function call.
Parentheses are not optional when calling a function except when it's being called via the new operator. Thus:
function foo() {
console.log("hi!");
}
var otherFoo = foo; // no function call
var obj = new foo; // function call via "new"
var x = foo(); // function call via "()"

How do I set a javascript variable to the return of an inline function?

I'm using the code:
var x = function() {return true;};
trying to set x to true, the return value of the function, but instead x is defined as the function itself. How can I set x as the return value of the function? I could easily code around this problem by using a non-inline function or some such, but it bugs me because I'm sure there must be a simple solution.
Thanks.
The solution is to define the function and then invoke it (by adding the extra parentheses at the end):
var x = ( function() {return true;} ) ();
You're not executing the function, you're setting x to actually be the function.
If you had some variable y, it could take on the value of the function with something like:
var x = function(){ return true; };
var y = x(); // y is now set to true.
or alternatively execute the function in place with:
var x = (function(){ return true; })();
Your code just defines the function and assigns it to x, the function doesn't get called. To call it, put the function in parenthesis and add () after it, like for a normal function call:
var x =
(
function () {
return true;
}
)();

Categories

Resources