Please explain me this higher-order function javascript code - javascript

I'm studying higher order functions following the Eloquent JavaScript book.
I haven't been able to understand this code, why is "Boolean" passed as noisy first argument?
This is supposed to be function that changes other function, I just don't get how it works!
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val; };
}
noisy(Boolean)(0);
// → calling with 0
// → called with 0 - got false

noisy accepts any one-argument function as its argument. It returns a new function that calls that function, but displays messages before and after it calls it.
Boolean is just an example function that they used. It converts its argument to a boolean datatype.

Boolean is a constructor function for the Boolean type. It could be any function.

Related

How can I log the result of a function that returns a function?

I'm trying to log a function that returns the result of a function as so:
function rutRow(x){
return function(){
return x;
}
}
console.log(rutRow(4)); // expect 4, getting function(){ return x; }
It is call currying. When you call rutRow(4) it retuns another function not value. Let's do it with adding an extra parenthesis () for your case to get the expected data 4
Currying Named after Haskell Brooks Curry, currying is the process of breaking down a function into a series of functions that each take a single argument.
It works like this way,
It accepts one argument and returns one function. The returned
function also accepts one argument and also returns another function
that also accepts one argument and …
function rutRow(x) {
return function() {
return x;
}
}
console.log(rutRow(4)());
See more: https://hackernoon.com/currying-in-js-d9ddc64f162e

How to check if a callback function passed as a parameter in Javascript has arguments or not?

I have to do this
doSomething
.then(success)
.catch(failure);
And success and failure are callback functions which will get their value at run time (I am trying to write a module).
So I have to know that the function failure which is sent as a callback should have a parameter.
Because the callback is supposed to be like
function(error) {
// An error happened
}
Is there anyway in JS to do this? Or any library that makes this kind of checking possible?
EDIT
Just to clarify. I want a user(not end user), who uses my module, to send in a function as a parameter which will become a callback and I want to check if the function sent, which will be called back, has enough parameters required. I understand it is up to one who uses it to take care of that. But why not try?
With a promise callback (your then and catch handlers), they will only be passed a single argument when called, and will always be passed that argument. (If the promise is obeying native semantics; jQuery's Deferred doesn't always.)
In the general case:
Usually you don't care, because in JavaScript, you can call a function with either fewer or more arguments than it has formal parameters. That is, this is just fine:
function foo(a) {
console.log("a = " + a);
}
foo(); // Fewer arguments than params
foo(1, 2, 3); // More arguments than params
Another reason you don't care is that the function can use arguments even when it doesn't declare formal parameters for them, by using a rest parameter or the arguments pseudo-array (you'll see why this snippet logs foo.length and bar.length in a moment):
function foo() {
console.log("First argument: " + arguments[0]);
}
function bar(...rest) {
console.log("First argument: " + rest[0]);
}
foo(1); // First argument: 1
bar("a"); // First argument: a
console.log("foo.length = " + foo.length); // foo.length = 0
console.log("bar.length = " + bar.length); // bar.length = 0
So just define what your API will call the callbacks with, and do that, and it's up to the users of the API to ensure that they use what you call them with correctly.
On those occasions it matters, you can use the function's length property to know how many formal parameters it declares:
function foo(a) {
console.log("a = " + a);
}
console.log(foo.length); // 1
Note that that will tell you how many formal parameters are declared...
...not counting a rest parameter (...identifier)
...only up until the first parameter with a default value (even if there are ones without a default after it)
So for instance:
function foo(a, b = false, c) { // b has a default value
console.log("a = " + a);
}
console.log(foo.length); // 1, even though `c` has no default value,
// because `c` is after `b`
and
function foo(a, ...rest) {
console.log("a = " + a);
}
console.log(foo.length); // 1, because the rest parameter doesn't count
It's probably an anti pattern for the caller to enforce a certain number of arguments of a callback, but if you must you can check the length of the function:
function test() {}
function test1(a) {}
function test2(a, b) {}
console.log(test.length, test1.length, test2.length)
I need to know whether the function which is sent as a callback should have a parameter
You need to read the documentation of the function that you are sending the callback to. It will mention how (when, how often, and with what arguments) the callback is called.
For your failure that means reading the docs for catch (assuming doSomething is a native promise). It says that the callback will be called with one argument, the rejection reason, when the promise is rejected.
Or any library that makes this kind of checking possible?
You can use a typechecker that will warn you or throw an error when the function you are passing does not have the expected number of parameters.

Eloquent Javascript: Higher Order Functions

I'm going through Eloquent Javascript: Higher Order Functions example below and already read questions and answers here and here. But I'm still very confused.
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
noisy(Boolean)(0);
// → calling with 0
// → called with 0 - got false
How can (0) be passed into noisy(f) since noisy() only takes one parameter and that is (Boolean)? I can see the inner function f(arg) is basically Boolean(0), but I don't understand how two parameters can get passed into a function that only allow one parameter. Would "noisy(Boolean)(0)(1)(2)(3);" be a valid function call? If so, how would you differentiate each value after Boolean within the noisy function? Which value will be referenced by "arg"?
The book noted the example function is modifying another function. Which function is being modified? I'm not understanding what the author meant by "modified".
but I don't understand how two parameters can get passed into a
function that only allow one parameter
noisy returns a function, Boolean is passed to noisy, 0 is passed to anonymous function returned from noisy, where f is Boolean, val becomes Boolean(0).
For example
function fn1(arg1) {
return function fn2(arg2) {
console.log(arg1, arg2)
}
}
// Call fn1, inside fn1 fn2 is called with `"b"` as parameter.
fn1("a")("b") // `a b`, `fn2`
This is the concept of currying in JavaScript where you can curry functions to return partially applied functions or pass in other functions
How can (0) be passed into noisy(f) since noisy() only takes one parameter and that is (Boolean)?
The answer to this is the curried function noisy() which expects a function f as parameter and returns another function. The returned function has a closure over noisy and as a result it can identify that Boolean was passed as parameter to noisy even after it was returned. That's why calling noisy(Boolean)(0) basically substitutes f=Boolean, arg=0
Refer this for more on currying: http://javascript.crockford.com/www_svendtofte_com/code/curried_javascript/ and closures: https://developer.mozilla.org/en/docs/Web/JavaScript/Closures

How does this function modify the other? (Higher Order Functions)

What is this code doing? How is it executing? What is x equal to?
Another useful type of higher-order function modifies the function value it is given:
function negate(func) {
return function(x) {
return !func(x);
};
}
var isNotNaN = negate(isNaN);
show(isNotNaN(NaN));
The function negate() returns a Function object that, when called, will return !func(x); for whatever argument x is passed. This Function object is being stored in the variable isNotNaN with func bound to the built-in function isNaN(). In the next line the function object stored in isNotNaN is being called with the argument NaN (a JavaScript keyword). It is at this point that x becomes bound to NaN. The return value is passed to the function show() (which isn't shown here).
For more info, read up on JavaScript functions here and consult the docs for JavaScript's Function object and function expression.
EDIT: Why do this? Sometimes it's useful to have a function that inverts a given boolean function. For instance, suppose you have some complex predicate and you want to filter an array for all elements for which the predicate is false. You can use negate() to turn the predicate function into a function that evaluates to true for those elements and just use Array.prototype.filter() to do the job. Think of it as a utility function that saves you having to write a lot of function(x) { return !predicate(x); } every time you want the inverse of a boolean-valued function. It's kind of trivial, but a lot of JS libraries (e.g., underscore.js, jquery, etc.) have a boatload of utility functions like this.
P.S. I would have written it more generally:
function negate(func) {
return function() {
return !func.apply(null, arguments);
};
}
That way, it can be used with boolean-valued functions of an arbitrary number of arguments.

Passing "extra" arguments to a function stored in a variable - Javascript

I'm new to Javascript, I'm self-teaching, so this might be an obvious area, but no matter how I phrase the question I can't really seem to get my head around this one issue. At the moment I'm reading through http://eloquentjavascript.net/chapter6.html (which was on mozilla's MDN). I've come across this a couple of times now, I would just like a simple break down if possible.
function negate(func) {
return function(x) {
return !func(x);
};
}
var isNotNaN = negate(isNaN);
show(isNotNaN(NaN));
I don't understand how at the very last step isNotNaN (a variable) is passing an 'extra argument' (NaN) to the function stored in isNotNaN (negate(isNaN). "show(isNotNaN(NaN));"
I came across this same problem when the concept of enclosure was trying to be explained. But I don't get where this argument "NaN" is going in the above function, as it seems to me like the last statement ends up something like:
show(negate(isNaN, NaN));
I would be happy to provide more details. This concept of passing an extra argument to a variable already holding a function with an argument confuses the hell out of me!
There's no "extra" argument. The negate() function itself returns a function defined as a function expression, which can then be called with any number of original (not extra) arguments passed. A closure is used for the returned function to keep a reference to isNaN as func.
var isNotNaN = negate(isNaN);
At this point, isNotNaN contains a reference to the function
function(x) {
return !func(x);
};
Again, func here refers to the isNaN argument passed to the negate function, which is the immediate parent in the scope chain. The result is similar, but not the same as
var isNotNaN = function (x) {
return !isNaN(x);
};
The reason it is not the same is, if we change the value of isNaN, the behaviour of this function will change. In the example you posted, however, the value of func is equal to the original value of isNaN and cannot be changed by anything outside of its scope thanks to the closure.
Essentially, you can pass in any function and get a new function that returns the negated result of the original function in return. For example:
var isNotArray = negate(Array.isArray);
isNotArray(12);
//-> true
In fact, negate(isNaN) simply return a function to the variable isNotNaN. This function take a parameter (named x in your case), then execute the function isNaN on the parameter before negating it and returning the result.
Perhaps this example can clear some things out for you regarding closures:
function foo(x){
function bar(y){
return x+y;
}
return bar;
}
var fooRef = foo(1); // fooRef references foo() with x set to 1
console.log(fooRef(2), foo(1)(2)); // 3, 3
http://jsfiddle.net/ePwy8/

Categories

Resources