Best way to identify the caller of a JavaScript function - javascript

I have a JavaScript function that needs to behave differently if is called from another function. I have no control of the invocation of my function, so I can't do that based on parameter passing.
So, I was planning on identifying which function is doing the call, and behaving differently if that call comes from this specific function. To do that, I found these approaches:
Get the reference through arguments.caller, but I found it is a soon-to-be deprecated attribute.
Get the reference through Function.caller, but it is not a standard.
So every approach I found seems to have a pitfall. Which is the recommended approach for that? By the way, I'm using ExtJS Framework, maybe there's an specific way for doing that there.

You can also intercept the function call and add an extra parameter... mroe detail here : http://www.vinylfox.com/patterns-using-ext-js-sequence-and-intercept/
There is a solution for your implmeentation here: https://stackoverflow.com/a/22165274/1386469

Related

Best Practice for Callback Parameters in NodeJs

Background
I'm the maintainer of a low level library for fast object traversal in Node.js. The focus of the library is speed and it is heavily optimised. However there is one big slowdown: Callback Parameters
The Problem
Callbacks are provided by the library consumer and can be invoked many, many times per scan. For every invocation all parameters are computed and passed to the callback. In most cases only a fraction of the parameters are actually used by the callback.
The Goal
The goal is to eliminate the unnecessary computation of these parameters.
Solutions Ideas
Ideally NodeJs would expose the callback parameters as defined by the callback. However obtaining them doesn't seem to be possible without a lot of black magic (string parsing). It would also not solve the situation where parameters are only required conditionally.
Instead of trying to obtain the parameters from the callback, we could require the callback to expose the required parameters. It sounds very inconvenient and error prone and would also not solve conditionally requires.
We could introduce a different callback for every parameter combination. This sounds like a bad idea.
Instead of passing in the parameters directly, we could pass in a function for each parameter that computes and returns the parameter value. Inside the callback the parameter would then be invoked as required. It's ugly but might be the best approach?
Questions
How do other libraries solve this?
What are other ways this can be solved?
This is a very fundamental design decision and I'm trying to get this right.
Thank you very much for your time! As always appreciated!
You could pass to the callback an object that has various methods on it that the client using the callback could call to fetch whatever parameters they actually need. That way, you'd have a clean object interface and you'd only compute the necessary information that was actually requested.
This general design pattern is sometimes called "lazy computation" where you only do the computation as required. You can use either accessor functions or getters, depending upon the type of interface you want to expose.
For performance reasons, you can perhaps reuse the same object for each time you call the callback rather than building a new one (depends upon details of your implementation).
Note that you don't even have to put all the information needed for the computation into the object itself as the methods on the object can, in some cases, refer to your own local context and locally scoped variables when doing their computation.
However there is one big slowdown: Callback Parameters
Did you actually benchmark this? I doubt constructing the argument values is that costly. Notice that if this is a really heavily used call, V8 might be able to inline it and then optimise away unused argument values.
Ideally NodeJs would expose the callback parameters as defined by the callback.
Actually, it does. If you do want to rely on this property though, you should properly document that you do, otherwise this magic could lead to obscure bugs.
We could introduce a different callback for every parameter combination. This sounds like a bad idea.
It doesn't seem to be that much of a problem to provide two options, filter(key, value) and filterDetailed(key, value, context). If the optimisation is really worth it, and as you say this is a low-level library, just go for it.
Instead of passing in the parameters directly, we could pass in a function for each parameter that computes and returns the parameter value. Inside the callback the parameter would then be invoked as required. It's ugly but might be the best approach?
Constructing a closure object to pass instead of a parameter does have some overhead as well, so you will need to benchmark this properly. It might not be worth it.
However, I see that you are actually passing a single context object as the argument on which the computed values are accessed as properties. In that case, you can simply make these properties getters that will compute the value when they are accessed, not when the object is constructed.

In Java/Swing, why do we use classes for action listeners?

This question is for my own curiosity.
In javaScript, we use addEventListener to assign methods to event callbacks, in Java, we use addActionListener, but we use entire classes that only have a single method in them. Why use a class with a single method instead of a simple callback function? That's basically what's happening anyway because our callback class only needs one method.
Why use a class with a single method instead of a simple callback function?
Simply put, because that's not always the case.
Conceptually, the idea is the same, it's based on the Observer Pattern, but rather than providing a function pointer, you're providing a class reference, but because classes can have multiple methods, you need a way for the event generator to know which method it should call.
Some event listeners are simple, like ActionListener, which only have a single method, but some are more complex, such as AncestorListener, MouseListener, WindowListener, which can respond to multiple different events.
The point is, the event listener interface defines the expected contract that the caller expects the recipient to conform to. interfaces are a key aspect of the Java language and how you use them is a very important concept to come to grips with.
You can use inner or anonymous class to make life easier and more recently you can also use lambda expressions, but essentially, they are still generating a class reference, it just makes it easier to write
Basically because Java didn't have first-class functions until recent versions. So that was the only way to pass different behaviors around.
in Java8 you could use lambda expression
button.addActionListener(e -> System.out.println("Clicked"));
or
button.addActionListner(containingObject::instanceMethodName) ;

Why is a more convoluted jQuery pattern necessary here?

To me, the following code seems reasonable enough:
$("#oneButton").click(
alert("hello");
);
It seems to say that when OneButton is clicked, please pop up an alert saying "hello".
However, in reality, the alert pops up regardless of whether the button is clicked or not.
One has to wrap alert("hello"); in an anonymous function, and THEN (and only then), the alert popping up will depend on clicking the button. To me this seems unnecessarily convoluted.
There must be a good reason why the designers of jQuery thought it acceptable for the alert in the code above to pop up even when the button hasn't been clicked. What is this reason?
Fair question I guess, although I'm not a fan of the arrogance that came with it :)
Lets break this down a bit:
object.method(function() {
alert('hi');
});
Your question is, why can't I skip the anonymous function?
What we're really doing here, is telling method to execute something at a later point. What's being executed is being supplied as a function.
We could simply give it a reference to a function instead!
object.method(alert);
Here's the problem, we've sent it a function, but now we can't send it any arguments. If we want to bring arument along to method, we must use ( and ).
As soon as those characters are included, the alert will instead get executed and the result of alert will get sent to method.
Now why can't this also be sent by reference? A very simple reason, you need some way to also pass the result of a function as an argument to another function, and the javascript engine cannot distinguish if your intent is to:
Send the result of a function as an argument to this other function, OR
Send a reference to the function with certain arguments to the other function.
Using ( and ) on a function means calling it immediately in almost every programming language, and javascript is no different.
There is a workaround:
object.method(alert.bind(this, "hi"));
Because .click() is a function and it may need a/some parameter/s to be used properly.
.click() alone will only trigger the event.
But .click(parameter) will do what's in the parameter after the event has been triggered. In this case parameter is a callback, i.e a function called after the main function finished.
But for the callback to be called, you will have to create a function.
Either by naming one:
function alertThis(){
alert('hello');
}
$("#oneButton").click(alertThis);
Or:
$("#oneButton").click(function(){
alert('hello');
});
The language could only provide a less verbose syntax for functions (look at coffeescript), but it's ok for library functions to execute immediately, so you can wrap them and pass code around when needed.
What do you suggest instead? I can only think of one alternative approach where primitive API return themselves a function, but that would lead to uglier code when you need to combine multiple primitives (even with direct syntax support by the language):
$(btn).onClick(alert().andThen(blink()).andThen(log()));
And also you would be forced to call
alert()()
When you need to display the dialog immediately.
The problem is that Javascript has no macros (with the meaning of Lisp) and the only way to provide "code" to a function is by passing a function/closure object.
click is just a regular method and accepts a parameter that is "code" to execute when the button is clicked. As for any parameter however the expression passed to click is evaluated when making the call and not later when user clicks the button.
To have click to work as you like the syntax should handle click differently than other function calls and this is what is allowed for example in Lisp by using macros instead of functions. Javascript has no macros and the syntax is fixed in the language: it doesn't have a click special form and you cannot create one.
The situation is not that terrible because Javascript syntax allows for inline anonymous functions so basically you just need to wrap your "code" parameters with function(){...} at the call site to get it working.
In Python for example things are a bit more annoying because only extremely simple functions can be specified inline as the lambda form can be used to specify anonymous inline functions but has serious limitations and doesn't allow any statement but just a single expression.

get all calls to a function in javascript

Is there a way to find all the functions that call another function? (And then by extension, all the functions that call those functions, etc.)
My guess is it won't be possible for all cases, but certainly it could be done for most use cases, no? Like if somebody defines their function as:
new Function('a','b', 'return a'+'+b;');
it might be more tricky to find inner references.
Thanks in advance.
There is a arguments.caller but it's deprecated. Function.caller is replacement but you need function name - I'd use arguments.callee or directly the name.
https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/caller
In addition to its excellent outline view, Eclipse lets you "focus" the calls of a function in the source by selecting its declaration and then pressing F2. Appearances will be displayed in the right bar.

How to listen to elements method calls in Javascript

I would like to listen to method calls.
For example, when an element is appended by anything to the document, I would like to be passed that element to act on it, like:
//somewhere
aParent.appendChild(aChild);
//when the former, a function I defined as listener is called with the aChild as argument
Does anybody know how to do that?
don't know if that's possible with the core functions, but you could always create your own functions, for the actions you want to monitor:
function AppendChild(oParent, oChild) {
// your stuff on oParent
// append oChild
oParent.appendChild(oChild)
}
or, maybe, modify the actual appendChild(), but that would be tricky...
I know that the Dojo Toolkit provides this functionality. You can some explanation here - jump to the section that says "Connecting Functions to One Another". If you are interested, you can look at the source of dojo.connect to see what's going on.
In Firefox you could rewrite Node.prototype.appendChild to call your own function (saving the original appendChild first, then calling it within) to perform additional actions.
Node.prototype._appendChild = Node.prototype.appendChild;
Node.prototype.appendChild = function myFunct(el){....; this._appendChild(el);}
Internet Explorer doesn't implement these interfaces (but there might be a workaround floating around, maybe using .htc..). IE8 will have Element instead of Node.
What you're describing is Aspect Oriented programming. In AOP parlance, your "join point" would be element.appendChild(), and your "advice" is the function that you would like to execute (before and/or after) every matching join point executes.
I've been keenly interested in possibilties for JavaScript AOP this for some time, and I just found this Aspect Oriented Programming and javascript, which looks promising without needed to adopt a big old API. -- I'm really glad that you brought this up. I have uses for this, like temporary logging, timing code segments, etc.
Multiple browsers handle the DOM in different ways, and unfortunately the way IE handles things is not as powerful as the way Mozilla does. The easiest way to do it is by using a custom function like the one that Filini mentioned.
However you could also wrap the different browsers DOM objects in a facade and use it for all element access. This is a bit more work but you would then be able to handle all the browsers in the same way and be able to add/remove listeners with ease. I'm not sure if it would be anymore useful than the custom functions, but worth a look at.

Categories