overriding a javascript function's return statement - javascript

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

Related

I need help understanding 'Once' function by David Walsh

I'm trying to understand exactly how this Once function by David Walsh works:
`
function once(fn, context) {
var result;
return function() {
if(fn) {
result = fn.apply(context || this, arguments);
fn = null;
}
return result;
};
}
// Usage
var canOnlyFireOnce = once(function() {
console.log('Fired!');
});
canOnlyFireOnce(); // "Fired!"
canOnlyFireOnce(); // nada
`
I understand it takes a function as a argument, and returns a function that calls the passed function only once.
But I'm trying to understand what each part is doing. Can anyone help explain? especially this part:
result = fn.apply(context || this, arguments);
Why the OR sign? what is "this" and how is it getting the arguments from fn? What purpose does 'context' serve?
I wrote a similar once() function for school that returns the result of the passed function, and stores the result to return it again if the function attempts to get called again. It took a lot of trial and error, and I'm just trying to get a firm grasp on all the component parts of how this works.
`
function add(x, y) {
return x + y;
}
function once(fn) {
let timesRan = 0;
let result;
function doOnce() {
if (timesRan === 0) {
timesRan = 1;
result = fn.apply(this, arguments); //I don't understand how this gets the arguments from AddOnce
console.log(`did it once: ${result}`)
return result;
} else {
return result;
}
}
return doOnce;
}
var addOnce = once(add);
console.log(addOnce(1, 2)); // test first call, expected value: 3
console.log(addOnce(2, 5)); // test second call, expected value: 3
console.log(addOnce(8, 22)); // test third call, expected value: 3
`
The concept behind this in JavaScript is confusing, because when I write a function such as:
function getPersonName() {
return this.name
}
I expect that this be defined as a some object with a name attribute. Depending on the scope, I may have this be defined and no problems! But in order for a function such as the above to properly reference this, we need to tell it what it should reference when we use that keyword.
For example, it allows us to do the following:
var canOnlyFireOnce = once(function() {
console.log(this.name)
}, {name: "John"});
canOnlyFireOnce() // prints John
canOnlyFireOnce() // nada
It may be helpful to understand the bind function's use cases in JavaScript to understand why having this (no pun intended) is useful.
The meaning of the this context in function.apply is already explained in rb612's answer.
For the question about arguments, you need to know that
the arguments object is a local variable available within all non-arrow functions. You can refer to a function's arguments inside that function by using its arguments object. 

Currying function work in javascript

Can someone please explain the below 'Currying' function. When I set a break point, I can see values 'b' and 'c' are undefined and returned. But how does the system get the value 7 for 'b' and 9 for 'c' in this case. Its printing the correct result for 5*7*9, ie 315 in console.
function multiply(a){
return function (b){
return function (c) {
return a*b*c ;
}
}
}
var answer = multiply(5)(7)(9);
console.log(answer);
When you call multiply(5) a function is returned and that function is immediately called with multiply(5)(7) and have access to a and b, then a new function is returned and is also immediately called when multiply(5)(7)(9) and has access to a, b, and c.
The answer to why the nested functions have access to parent function parameters is closures. Please check this other question/answers about closures in javascript: link.
You can understand currying if you assign each intermediate result to a variable. Rewrite the function calls like this:
var x = multiply(5)
var y = x(7);
var answer = y(9);
Now it is more clear that the result of calling multiply(5) is a function. We call it with x(7) which passes the value of 7 to b. This results in another function which we call with y(9) which in turn passes the value of 9 to c and returns the final result.
When you call the multiply function, the important thing is each function returns an anonymous function. It will be easier if you give them names.
function multiplyA(a){
return function multiplyB(b){
return function multiplyC(c) {
return a*b*c ;
}
}
}
// When you call multiplyA(5)(7)(9)
// From the first, multiplyA(5) returns multiplyB with scope with multiplyA
// just like below
const a = 5;
const multiplyB = function(b){
return function multiplyC(c) {
return a*b*c ;
}
}
// Once more call multiplyB(7)
// It also returns function named multiplyC
const a = 5;
const b = 7;
const multiplyC = function(c) {
return a * b * c;
}
// Finally call mulitplyC(9) means 5 * 7 * 9
To understand it, closure and function scope will be helpful.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

Understanding javascript call function

'use strict';
let worker = {
someMethod() {
return 4;
},
slow(x) {
return x * this.somemethod();
}
};
function wrapper(func) {
return function(x) {
let result = this.func(x); // **
return result;
};
}
worker.slow = wrapper(worker.slow);
alert( worker.slow(2) );
When I run this code I get this error:
TypeError: this.func is not a function
If I replace the problematic line at ** with this:
let result = func.call(this, x);
I get the expected output. In this case it's 8.
I'm wondering why the way it's written is the wrong way to get "this" ie the object worker. In other words, how does the call function get the right object i.e. worker ?
The reason it's failing is that in the problematic line (highlighted with // **), you're effectively calling worker.func(x), which does not exist; You're not referring to the passed in variable at all.
If you add a function (func) to your worker, e.g.
let worker = {
someMethod: function() {
return 4;
},
slow: function(x) {
return x * this.somemethod();
},
func: function (x) {
return x * 10;
}
};
And call as above e.g.
worker.slow = wrapper(worker.slow);
console.log( worker.slow(2) );
You'd find it works, though this is not what you really want!
In JavaScript, any function call obj.f(ArgumentList) will be desugared into f.call(obj, ArgumentList...)(see ecma-262 7.3.12)
When wrapper(worker.slow) got a call, the function slow is passed into the wrapper and it produces another function which captured func argument. However, that function returned by wrapper is not called yet.
At a moment of the function call alert( worker.slow(2) )
func mean the argument that got captured in the closure and func.call(this, x) means it will call that function with the current caller, which is worker.
Therefore, `func.call(this,x)` will be `func.call(worker, x) `
which works because `func` exists in the closure.
while this means the reference to a current caller to the function(x){ ... }
Hence, `this.func(x)` will be `worker.func(x)`
which `func` does not exist in `worker`.
if you try to insert console.log(func) and console.log(this)
in that function, you will see the difference.

Understanding the syntax of a deferred execution chain

I'm getting around to learning JavaScript - really learning JavaScript. I come from a PHP background so some JavaScript concepts are still new to me, especially asynchronous programming. This question might have already been answered many times before but I have not been able to find an answer. It might be because I don't really even know how to ask the question other than by showing an example. So here it is:
When using the deferred package from npm, I see the following example:
delayedAdd(2, 3)(function (result) {
return result * result
})(function (result) {
console.log(result); // 25
});
They refer to this as chaining and it actually works as I'm currently using this code to check when a promise is resolved or is rejected. Even though they call it chaining, it reminds me of trailing closures like in Swift.
I don't really understand what type of chaining this is since we have a function invocation and then immediately after, an anonymous function enclosed in parentheses.
So I guess I have two questions.
What pattern is this?
How does it work? This may be a loaded question but I like to know how something works so when someone asks me about this I can give them a detailed explanation.
Here is the delayedAdd function:
var delayedAdd = delay(function (a, b) {
return a + b;
}, 100);
which uses the following function:
var delay = function (fn, timeout) {
return function () {
var def = deferred(), self = this, args = arguments;
setTimeout(function () {
var value;
try {
value = fn.apply(self, args));
} catch (e) {
def.reject(e);
return;
}
def.resolve(value);
}, timeout);
return def.promise;
};
};
It's actually really easy to understand. Let's look at what's going on here when the expression is evaluated:
First the delayedAdd(2, 3) function will be called. It does some stuff and then returns. The "magic" is all about its return value which is a function. To be more precise it's a function that expects at least one argument (I'll get back to that).
Now that we evaluated delayedAdd(2, 3) to a function we get to the next part of the code, which is the opening parenthesis. Opening and closing parenthesis are of course function calls. So we're going to call the function that delayedAdd(2, 3) just returned and we're going to pass it an argument, which is what gets defined next:
That argument is yet another function (as you can see in your example). This function also takes one argument (the result of the computation) and returns it multiplied by itself.
This function that was returned by the first call to delayedAdd(2, 3) returns yet another function, which we'll call again with an argument that is another function (the next part of the chain).
So to summarize we build up a chain of functions by passing our code to whatever function delayedAdd(2, 3) returned. These functions will return other functions that we can pass our functions again.
I hope this makes the way it works somewhat clear, if not feel free to ask more.
mhlz's answer is very clear. As a supplementary, here I compose a delayedAdd for your to better understand the process
function delayedAdd(a, b) {
var sum = a + b
return function(f1) {
var result1 = f1(sum)
return function(f2) {
f2(result1)
}
}
}
Where in your example code, the function you passed as f1 is:
function (result) {
return result * result
}
and f2 is:
function (result) {
console.log(result)
}
Functions are first-class citizens in JS - that means (among others), they can take the role of actual parameters and function return values. Your code fragment maps functions to functions.
The signatures of the functions in your chained call might look like this.
delayedAdd: number -> fn // returns function type a
a: fn ( number -> number) -> fn // returns function type b
b: fn ( number -> void ) -> void // returns nothing ( guessing, cannot know from your code portion )
General setting
Of course, JS is a weakly typed language, so the listed signatures are derived from the code fragment by guessing. There is no way to know whether the code actually does what is suggested above apart from inspecting the sources.
Given that this showed up in the context of 'chaining', the signatures probably rather look like this:
delayedAdd: number x number -> fn (( fn T -> void ) -> ( fn T -> void ))
Which means that delayedAdd maps two numbers to a function x, which maps functions of arbitrary signatures to functions of the same signature as itself.
So who would do anything like this ? And why ?
Imagine the following implementation of x:
//
// x
// Collects functions of unspecified (possibly implicit) signatures for later execution.
// Illustrative purpose only, do not use in production code.
//
// Assumes
function x ( fn ) {
var fn_current;
if (this.deferred === undefined) {
this.deferred = [];
}
if (fn === undefined) {
// apply functions
while ( this.deferred.length > 0 ) {
fn_current = this.deferred.shift();
this.accumulator = fn_current(this.accumulator);
}
return this.accumulator;
}
else {
this.deferred.push ( fn );
}
return this;
}
Together with a function delayedAdd that actually returns an object of the following kind ...:
function delayedAdd ( a1, a2) {
return x ( function () { a1 + a2; } );
}
... you'll effectively register a chain of functions to be executed at some later point of time (e.g. in a callback to some event).
Notes and reminders
JS functions are JS objects
The signatures of the registered functions may actually be arbitrary. Considering them to be unified just serves to keep this exposition simpler (well ...).
Caveat
I do not know whether the outlined codeis what node.js does (but it could be ... ;-))
To be fair this pattern can be either chaining or currying(or partial application). Depending how it's implemented. Note this is a theoretical answer to provide more information about the pattern and not your specific use case.
Chaining
There is nothing special here because we can just return a function that will be called again. Functions in javascript are first class citizens
function delayedAdd(x, y) {
// In here work with x and y
return function(fn) {
// In here work with x, y and fn
return function(fn2) {
//Continue returning functions so long as you want the chain to work
}
}
}
This make it unreadable in my opinion. There is a better alternative.
function delayedAdd(x, y) {
// In here work with x and y
return {
then: function(fn) {
// In here work with x, y and fn
return {
then: function(fn2) {
//Continue returning functions so long as you want the chain to work
}
}
}
}
}
This changes the way your functions are called from
delayedAdd(..)(..)(..); // 25
is transformed to
delayedAdd().then().then()
Not only is more readable when you are passing several callback functions but allows a distinction from the next pattern called currying.
Currying
The term cames after the mathematician Haskell Curry. The definition is this
In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument (partial application). It was introduced by Moses Schönfinkel and later developed by Haskell Curry.
Basically what it does is take several arguments and merge with the subsecuents and apply them to the original function passed in the first argument.
This is a generic implementation of this function taken from Stefanv's Javascript Patterns.
{Edit}
I changed my previous version of the function to one which has partial application included to make a better example. In this version you must call the function with no argument to get the value returned or you will get another partially applied function as result. This is a very basic example, a more complete one can be found on this post.
function schonfinkelize(fn) {
var slice = Array.prototype.slice,
stored_args = [],
partial = function () {
if (arguments.length === 0){
return fn.apply(null, stored_args);
} else {
stored_args = stored_args.concat(slice.call(arguments));
return partial;
}
};
return partial;
}
This are the results of the application of this function
function add(a, b, c, d, e) {
return a + b + c + d + e;
}
schonfinkelize(add)(1, 2, 3)(5, 5)(); ==> 16
Note that add (or in your case delayedAdd) can be implemented as the curying function resulting in the pattern of your example giving you this
delayedAdd(..)(..)(..); // 16
Summary
You can not reach a conclusion about the pattern just by looking at the way the functions are called. Just because you can invoke one after the other it doens't mean is chaining. It could be another pattern. That depends on the implementation of the function.
All excellent answers here, especially #mhlz and #Leo, I'd like to touch on the chaining part you've mentioned. Leo's example shows the idea of calling functions like foo()()() but only works for fixed number of callbacks. Here's an attempt to imlpement unlimited chaining:
delayedAdd = function da(a, b){
// a function was passed: call it on the result
if( typeof a == "function" ){
this.result = a( this.result )
}
else {
// the initial call with two numbers, no additional checks for clarity.
this.result = a + b;
}
// return this very function
return da;
};
Now you can chain any number of functions in () after the first call:
// define some functions:
var square = function( number ){ return number * number; }
var add10 = function( number ){ return number + 10; }
var times2 = function( number ){ return number * 2; }
var whatIs = function( number ){ console.log( number ); return number; }
// chain them all!
delayedAdd(2, 3)(square)(whatIs)(add10)(whatIs)(times2)(whatIs);
// logs 23, 35 and 70 in the console.
http://jsfiddle.net/rm9nkjt8/3/
If we expand this syntax logically we would reach something like this:
var func1 = delayedAdd(2, 3);
var func2 = function (result) {
return result * result
};
var func3 = function (result) {
console.log(result);
};
var res = func1(func2); // variable 'res' is of type 'function'
res(func3);

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.

Categories

Resources