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.
Related
I want to debug a website that is built from millions of lines of js code, and I want to find the function that will receive a specific value as one of the arguments. Is it possible to break the execution when any function receive a specific value as one of the arguments?
You could add a conditional breakpoint in
Chrome's debugger
Firefox' debugger
Alternatively, if the browser of your choice does not have similar functionality, you could invoke the debugger statement conditionally (if you can modify the code):
if(value === "wanted") debugger;
however that only works if you know the functions that might receive a specific parameter
Is it possible to break the execution when any function receive a specific value as one of the arguments?
No, that's close to impossible. Adding a breakpoint to "any function" will probably slow down execution a lot, if it's even possible. Doing so programmatically might work somehow, though it seems like a lot of work for little benefit. If you know the value, you probably also know the source and can debug from there.
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
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.
Okay:
document.addEventListener('mousemove', function (e) {...code...}, false);
Recently I realized that I could greatly enhance my interaction with a few websites by way of Chrome extensions to reorder and rewrite the website to suit my needs.
So, I've been trying to get a grasp of chrome extensions, javascript, css, dom, jquery and HTML. It is a huge subject and I am woefully unfamiliar with web technologies.
Can someone please explain what 'function(e){...code...}' is in this context?
It is an inline function without a name? So, unlike other languages, instead of creating a function with a name and then calling it when needed, this statement hooks the mousemove with an unnamed function?
I suppose it is a stupid question to ask what the benefit is to having an inlined unnamed function is?
function (e) {...code...} is a reference to an anonymous function to run on the occurence of the mousemove event. The e parameter is the event Object that is sent with the event itself.
So basically you say: everytime someone moves his/her mouse around somewhere in the DOM Object document, execute the function using the event Object I give you in the parameter of that function.
You could've also used (and this is sometimes advised for readability and clarity):
function mousemover(e){ ... }
document.addEventListener('mousemove', mousemover, false);
That is also the preferred way if you later on decide to remove the eventlistener (removeEventListener).
An inline anonymous function is sometimes called a lambda function. You can read about it in this SO Question.
As per request in the comments: in javascript functions are first class objects. Specifically, this means that the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures (quoted from this wikipedia page). Also read more on Douglas Crockfords page.
They are called anonymous functions.
You can read a little more about them here:
http://en.wikipedia.org/wiki/Anonymous_function#JavaScript
Inlined (anonymous) functions are just a style thing, allowing for shorter code. They can also avoid polluting the namespace by introducing unneeded names into the current scope.
However in this particular case there is a downside in that it's impossible to remove a specific event listener if it was added anonymously.
I have this piece of code that I've written and read that in order for it to work correctly I must use parameters so I did and it works perfectly, however I cant figure out for the life of me what parameters are and how they work. I read through a ton of articles all over the web but I just couldn't figure out how parameters work. How does one parameter know to grab instructions from another. The whole idea is just really frustrating. Also this is kind of a side question. Can I getElementBy Class instead of Id or is there anything similar to get getElementById() for classes? Thanks so much in advance.
Below is the code that is in the script.js file:
function setValue(field)
{
if(''!=field.defaultValue)
{
if(field.value==field.defaultValue)
{
field.value='';
}
else if(''==field.value)
{
field.value=field.defaultValue;
}
}
}
and I called this script to run with the code below:
<textarea id="info"
class="textArea"
name="comment"
cols="40" rows="10"
onfocus="setValue(this)"
onblur="setValue(this)">
Whats Your Name
</textarea>
Parameters
If by "parameter" you mean "argument", it's not at all clear what you mean by "How does one parameter know to grab instructions from another." Arguments/parameters don't grab "instructions" from each other.
Since it's not at all clear what you're actually asking here, I won't go into any kind of detail, but I will warn that function arguments actually work a bit differently in JavaScript than in many other languages like C, C#, or Java.
The traditional model is a special memory area called a "stack": The caller pushes arguments onto the stack, and the callee (the function being called) pulls them off the stack.
JavaScript doesn't use the stack model, though. Instead, when a function is called, an object called an execution context is allocated, and along with it something called a variable object, and the arguments (and a few other things) end up being properties on the variable object. (This happens invisibly behind the scenes, you don't actually get direct references to either object, but the fact of them is clear from edge case behaviors.)
Getting Elements by Class Name
There's getElementsByClassName which is widely-supported except by IE. But if you search for "getElementsByClassName IE" you'll find a variety of implementations for IE that you can drop into your page.
When I hear the word "parameter", I usually think of references that are passed into methods for execution. Is that what you mean? Whether it's a function or an object method, that's usually the name that we give to the object references that are passed in. Is that what you have in mind?
Yes, it's possible to query for a DOM element using div names, as long as you've written your page to do so. jQuery is the library that most people are using to manipulate the DOM in an HTML page. It has lots of methods for querying for different DOM elements. Perhaps that is what you want.
Well, I think many people call them parameters while many others call them arguments, but they are both the same: They are what you pass to a function. What that does with the parameters/arguments is completely dependent on the function. You could pass a DOM element, a string, an object, you name it.. but the function ultimately decides what to do with it.
Your side-question about getElementByClass, there is getElementsbyClassName, but its not cross-browser compatible, meaning it only works in certain browsers. There are libraries that handle all of the cross-browser madness for you though, such as Sizzle.