why this javascript decorate function doesn't work? - javascript

I am looking at decorate function. For example, decorate function can make sum() function to return a double sum. But the following code doesn't work as desired, I changed the 'f' to 'sum', please see comment on relevant line, why I cannot change this?
<script>
function doublingDecorator(f) {
return function() {
return 2*sum.apply(this, arguments); // the original code is: return 2*f.apply(this,arguments) I changed to sum, then doesn't work.
}
}
// Usage:
function sum(a, b) {
return a + b
}
var sum = doublingDecorator(sum); // sum gets decoration
alert (sum(3,4)); //return 14
</script>

f in doublingDecorator is not used. Instead you reference sum, which you also redefine. This causes an infinite loop.
function doublingDecorator(f) {
return function() {
return 2*f.apply(this, arguments);
// ^-- f instead of sum!
}
}
function sum(a, b) {
return a + b
}
var sum = doublingDecorator(sum); // note: sum is already declared here, redeclaring is technically wrong.
console.log(sum (3,4)); // 14

Two things:
You changed the inner f.apply to sum.apply.
You redefine sum.
That's why it's breaking. Your change makes it a recursive call that never ends (infinite recursion) because sum calls itself over and over again. This is because you reference sum inside, which you have also redefined.
Eventually the recursion ends up exceeding the maximum call-stack size.
I recommend leaving f.apply as it is. Then your code should work. Another option is to not redefine sum. So do this instead:
var newSum = doublingOperator(sum);
console.log(newSum(3, 4)); //returns 14

Related

JS, return function name

I've just started to learn javascript and come across one task that I don't understand. Can anyone explain me why do we return function name "return f" in this example and what for do we use "f.toString"?
function sum(a) {
var currentSum = a;
function f(b) {
currentSum += b;
return f;
}
f.toString = function() {
return currentSum;
};
return f;
}
alert( sum(1)(2) ); // 3
alert( sum(5)(-1)(2) ); // 6
alert( sum(6)(-1)(-2)(-3) ); // 0
alert( sum(0)(1)(2)(3)(4)(5) ); // 15
Lets start with a simplified version:
function sum(currentSum) {
return function f(b) {
currentSum += b;
return f;
}
}
It willwork much like yours, you can do:
sum(1)(2)(3);//f
sum(1)(2);//f
However, they always return a function, so were not able to access the currentSum. Its in sums scope and as its never returned or passed, its impossible to get it. So we probably need another function we can call to get the current sum:
function sum(currentSum) {
function f(b) {
currentSum += b;
return f;
}
f.getSum = function() {
return currentSum;
};
return f;
}
So now f has a property (functions are objects too), which is a function called getSum to get our variable
sum(1)(2)(3)//f
sum(1)(2)(3).getSum()//6 <= wohhooo
But why do we call it toString ?
When adding a variable to a string, its converted to a string, e.g.
1+"one"//"1one"
the same applies to objects/functions, but in this case, the js parser tries to call their toString method first, so:
sum(1)(2)+"three"
equals
sum(1)(2).toString()+"three"
the same conversion happens when passing non strings to alert.
You are returning the object. So you can call the function again and, in the second call, you will have a currentSum allready.
when you do sum(3) the function will hold the number 3 and when you call it again doing sum(3)(4) it will add 4 to the currentSum.
then the alert will call the toString method and it will print the sum
look at the first example
alert( sum(1)(2) ); // 3
sum(1) // will return f. sum must return a function in order for the syntax to work
after it will return f it will become:
alert( f(2) );
With function sum you are passing the first argument a and returning function f which sum currentSum with the argument passed to f (b) and return again f and you can do that many times you want at the end it will call alert function which needs its first argument to be string. For that purpose you have rewritten the method on function f toString which in this case will return the currentSum.
Every object has a toString() method that is automatically called when the object is to be represented as a text value.
This is the task for understanding the type system of JavaScript. The task is to make function that adds numbers using currying. The idea is to make function that adds numbers when called like this sum(1)(2)(3), as you written in the task.
What do we do (looking to your code) in function sum:
1.
var currentSum = a;
Here you declare a sum variable in scope of function sum.
function f(b) {
currentSum += b;
return f;
}
Then you declare the function that will perform summation. It returns itself for possibility of doing such thing: f(1)(2)(3)
3.
f.toString = function() {
return currentSum;
};
After that you declare that f, converted to string returns sum value
Than you return f to start adding.
Than what about f.toString - it 's being called, when f is passed alert as an argument. That's automatic casting of javascript

Create a function with an undetermined number of successive calls

As part of a programming challenge, we are tasked with creating a function with an undetermined number of successive calls. As an example, let's say the function returns simply the sum of the provided arguments, it should work as follows :
sum(4)() // 4
sum(4)(5)() // 9
sum(4)(5)(9)() // 18
sum(4)(5)(9)(1)() // 19
// etc...
The problem is simplified by the allowed empty function call at the end as an indication of end of calls.
I have worked on a solution that does the job but using global variables inside the function itself :
var sum = function (a) {
if (!sum.init) {
sum.total = 0;
sum.init = true;
}
if (!arguments.length) {
sum.init = false;
return sum.total;
}
sum.total += a;
return sum;
};
This solution works but uses state, global variables and function object trickery which is not ideal. My question here is whether there is a way to solve the problem in a purely recursive way.
As a side note, I do not believe the problem can be solved if that last empty call () is not provided, but if I'm wrong please let me know.
Update
This issue has been answered in CodeReview : https://codereview.stackexchange.com/a/153999/129579
A neet solution that does not rely on global scope and is purely functional.
You can make use of closures to acheive what you want like this:
function sum(value){
// the closure variable that will be accessible for all the _sum calls (initialised to 0 for every sum call).
var result = 0;
// the function that will be returned (sum will only get called once to initialize the result to 0. It's _sum which will be returned as much as possible)
function _sum(a){
// if we passed a parameter, then add it to result and return a new _sum
if(typeof a != "undefined"){
result += a;
return _sum;
}
// if we didn't return the result
else
return result;
}
// of course after initializing result we need to call _sum that handle the actual summing and return whatever it returns (if value is defined, it will return another `_sum` if not it will return the value of result which will be 0 at first) from now on sum will have nothing to do with the rest of the calls (()()()... )
return _sum(value);
}
console.log("sum() = " + sum());
console.log("sum(7)() = " + sum(7)());
console.log("sum(5)(6)(7)() = " + sum(5)(6)(7)());
// will return 0 because we call sum again
console.log("sum() = " + sum());
NOTE: That sum(1)(7)(3)()); will call, in this order:
sum with the parameter 1 which will initialize result to 0 and call
_sum with the same parameter 1 which will add it to result and return a new inctance of _sum which will be called so the following
_sum get called with the parameter 7, add it and return a new _sum so the new
_sum get called with the parameter 3, ... spawn another
_sum that will have no parameter, therefore if(typeof a != "undefined") will fail and this _sum will return result instead.
The actual sum is only called once at the begining to do the initialization. It's, as I said, _sum that get chained after that all the way to the end.
Basically you could use an outer function sum for the initial call and a closure over the starting value a and an inner function fn, which is repeatingly returned and only exited if arguments.length is equal to zero.
If a value b is supplied, the variable a gets updated and the inner function fn gets returned.
function sum(a) {
return function fn(b) {
if (!arguments.length) {
return a;
}
a += b;
return fn;
};
}
console.log(sum(1)());
console.log(sum(1)(2)());
console.log(sum(1)(2)(3)());
Edit for calling sum with no argument
function sum(a) {
return arguments.length ?
function fn(b) {
if (!arguments.length) {
return a;
}
a += b;
return fn;
} :
0;
}
console.log(sum());
console.log(sum(1)());
console.log(sum(1)(2)());
console.log(sum(1)(2)(3)());

When/why to use "return" in callback functions

I am trying to understand when should we use return, and when we shouldn't.
The returns used below are confusing to me. Please see the comments for my questions:
function each(collection, iterator) {
if (Array.isArray(collection)){
for (var i=0;i<collection.length;i++){
iterator(collection[i],i,collection)
}
}else {
for (var key in collection){
iterator(collection[key],key,collection)
}
}
};
function map(collection, iterator) {
var result = [];
// why we don't add "return" in front of the each() function here?
// why, if I add return, is the result "undefined"?
each(collection,function(value,key,collection){
result.push(iterator(value,key,collection));
})
return result;
};
function pluck(collection, key) {
// Why do we add "return" in front of map function, and
// why if I don't add it, the result is "undefined"?
return map(collection, function(item){
return item[key];
});
};
var car = [{type: "Fiat", model: "500", color: "white"}]
console.log(pluck(car,'type'));
Use return to have your function return a value; don't use it if the function doesn't need to return anything, or when you don't want to return yet.
In your example, if you just said:
function pluck(collection, key) {
map(collection, function(item){
return item[key];
});
};
map() would still be called, but the results of that map() would be discarded.
It's as though you'd written:
function add(a, b) {
var c = a + b; // computed, not returned
}
var result = add(1, 2); // undefined
instead of:
function add(a, b) {
var c = a + b; // computed
return c; // and returned
}
var result = add(1, 2); // 3
each() loops over a set of things, performing an action each time. It doesn't have a result to return.
And in your case, there's more code after the each() -- remember, return; ends the function from which it's returning.
// if we returned here
each(collection,function(value,key,collection){
// this isn't part of each's "value", it's just some code
// that runs within the each loop
result.push(iterator(value,key,collection));
})
// we'd never get here, to return the total result
return result;
Not exactly sure what your question is asking but I'm guessing you're comparing each versus map / pluck in the sense that each doesn't have an explicit return statement wheres map and pluck do have an explicit return statement.
A key point to note is that even though each doesn't have an explicit return statement, there is an implicit return undefined for every JavaScript function without an explicit return statement - which means that each also has an implicit return undefined.
The reason why each doesn't have a return statement is because you're NOT trying to return anything - instead, you're trying to do something to each item in a collection. For map and pluck, most libraries have defined it so that these functions are specified to return a collection.

How the parens work?

I have found a piece of code in my teacher s notes and I do not understand it.
The point is to find the value for "pass" for which the function would return TRUE.
Can you please answer to my questions below(comments), so I can understand how this works?
<script type="text/javascript">
function findPassword(pass)
{
var b = 1337
//How is this function returning "min" (without the parens?)
function add(x){
b += 84
return min
}
//Same question as above...for "mod" - how is this compiling?
function min(x){
b -= 123
return mod
}
function div(x){
b /= 3
return min
}
function mod(x){
b = b+5+(b%3)
return add
}
//what is the purpose of "fn" if it is not used at all?
var fn = function ()
{
b += 34
return div
}
//WHAT is happening here? "() () ()"
(function (){
b /= 3
return mod
})()()()
if(pass == b*b) {
return true;
} else {
alert("Wrong password !")
return false;
}
}
</script>
So looking at this:
(function (){
b /= 3
return mod
})()()()
You have this:
function (){
b /= 3
return mod
}
Which is a function. You wrap it in brackets and then call it with (), this is called a immediately invoked function expression (IIFE).
So what does it return? It returns mod, which is a function, so the next () will call that function.
What does mod return:
function mod(x){
b = b+5+(b%3)
return add
}
It returns the function add, which you invoke again with (). The function add happens to return the function min, but since we have no more (), we don't invoke it, so it's basically thrown away.
Now, none of this is to suggest this is a good way to structure your code, because it isn't.
As for what value will actually make findPassword return true? Well, you could follow what happens to b in each function.
...or, you could just stick a console.log(b); right after the IIFE to see it's value. The value of pass you need will be that number squared.
Just because nobody pointed out what the purpose of the function fn in this example is:
At first sight, it may seem that you've got an anonymous function self executing, and starting a chain of execution by doing so, however, that encapsulated anonymous function, and add, are actually the only functions in the code that don't execute, and that is because the declaration of fn, before it, is missing a semicolon:
var fn = function ()
{
b += 34
return div
} // <- missing semicolon.
// Because of this, the `var` statement doesn't stop in here.
Because of that missing semicolon, the parentheses encapsulating the anonymous function that comes after this function declaration, are actually executing fn, and passing the anonymous function as an argument to it (and fn is doing nothing with that argument). So, in reality, the code looks like this:
var fn = function ()
{
console.log(arguments[0]); // Logs the anonymous function
b += 34
return div
}(function (){
b /= 3
return mod
})()()()
// The parentheses () mean 'execute' this.
// If they are chained, they execute what the previous
// function returned.
// It is possible to do that when, like in this code, the functions
// return a function reference (meaning, the name of a function).
Which is pretty much the same as this:
var fn = function () {
b += 34/= 3
return div
}( /* Executing fn... */ )( /* div */ )( /* min */ )( /* mod */ )
// fn ends up containing a reference to add, because mod returns that,
// but add is never called.
console.log(fn === add); // true
The chain of execution is this:
fn => div => min => mod
So, to arrive at the password, you do:
var b = 1337;
b += 34;
b /= 3;
b -= 123;
b = b + 5 + (b%3);
// b === 340
// password is b^2: 340 * 340 = 115600
Of course, you can also console.log b, but what's the sense of that?
Follow the return statements and you'll see that they are functions, therefore adding () to that return value will evaluate it.
The first set of parens executes the function immediately before it. This returns mod which is a function. It gets executed by the second parens. This (mod) returns add which is, again, a function. So the last set of parens executes add. Which, in the end, returns min.
It's not very clear the way this program is running but it's essentially modifying that one variable and returning more functions to simulate some logic that modifies the variable in different ways depending on how you call the functions.

overriding a javascript function's return statement

Assume I have a js function. From some other point in the program, I want to run its code, but not its return statement. In its place, I would like to run some other return statement that references the variables in the scope of the original function.
Is there a way to do this, other than loading up the function source, replacing the return, and using eval on the result? Minimal modification of the original is possible, though it should not affect the original's performance by adding e.g. an extra function call.
You could try something like this, but I'm not sure it meets your conditions.
Edit: Fixed to work in jsfiddle
// Modified to set all "shared" variables as "members" of the function.
var test = function() {
test.val = "one";
test.val2 = "two";
return 1;
}
// Using different result
function test2() {
test();
return test.val2;
}
Unless you're able to restructure your methods to accommodate a callback or introduce some other parameter-based logic-flow (not an option for 3rd party code), you're out of luck.
Here's a callback sample (fiddle, credit to dzejkej's answer)
function foo(callback) {
var x = 2;
// pass your values into the callback
return callback ? callback.call(this, x) : x * 2;
}
document.write(foo());
document.write("<hr/>");
// specify the parameters for your callback
document.write(foo(function(x){ return x * 4;}) );
You can introduce a callback function that will get called if available otherwise "standard" value will be returned.
function test(callback) {
// ...
return callback ? callback.call(this) : /* original value returned */ "xyz";
}
test(function() { /* "this" is same as in test() */ });
EDIT:
If you want to pass variables inside callback then you just list them in the .call() function.
Example:
function test(callback) {
var a = 4;
var b = 2;
// ...
return callback ? callback.call(this, a, b) : a * b;
}
test(); // 8
test(function(a, b) { return a + b; }); // 6
See this fiddle.
Provided that you would keep variables of the outer scope function within a single object, you could try something like the following:
function original(a, b, c, rep) {
var data = {};
// Do some fancy stuff but make sure to keep everything under data
data.a = a.replace(/foo/, 'bar');
...
if ( Object.prototype.toString.call(rep) === '[object Function]' )
return rep.call(data);
return data;
}
function replacement() {
return 'foo' + this.a;
}
// Now let's make use of both the original and the replacement ...
console.log(original('foo', x, y)); // => {a: "bar", b: ...}
console.log(original('foo', x, y, replacement)); // => {a: "foobar", b: ...}
Hope, it's what you where asking for.
cheers
I think you really misunderstand the concept of return statement. The return statement of a function will simply return a value, or an object, or undefined if there is no return parameter specified.
If all you're trying to do is execute a function but "not its return statement" than you would just invoke the function and not do anything with the returned value/object:
However, if what you mean is that you would like to execute a function but not execute the "parameter" to its return statement then that literally means to selectively execute an arbitrary portion of the body of a function. And as far as I know that is not possible (without using reflection to get the function definition, modify the definition, and then dynamically invoking the modified version - which you said you didn't want to do).

Categories

Resources