Javascript: Understanding function syntax and parameters - javascript

I am trying to make sense of the onchange event of bootstrap-multiselect. In particular, I am trying to understand the function syntax and parameters.
$('#example-onChange').multiselect({
onChange: function(option, checked, select) {
alert('Changed option ' + $(option).val() + '.');
}
});
How to know what does the three parameters in the function mean? Where will I get these three parameters? I also tried looking at the code https://github.com/davidstutz/bootstrap-multiselect/blob/master/dist/js/bootstrap-multiselect.js#L263 but couldn't make much sense of it.
I know using alerts that in this function option refers to the selected option, checked shows whether the option was checked or unchecked. I keep getting undefined when doing console.log(select) inside the function, so not sure what does that mean.
Question: How to understand function parameters and syntax like these? This is just an example but knowing a generic procedure will help me decode other similar functions in future.

In short, it seems the library doesn't actually provide the select option.
In general, in situations where the documentation isn't very precise, the technique I often apply is to console.log the arguments, then inspecting what each of them look like.
In this situation, when doing:
$('#example-onChange').multiselect({
onChange: function(option, checked, select) {
console.log(arguments);
}
});
... I got the following output:
... from this you can see two arguments are provided. The first is the jQuery object of the option that was clicked. The second (you can assume) is a boolean as to whether the option is selected or not.
You can also see no select (3rd argument) was provided.
Another approach you can take is to search the source code, like you did; but I'd recommend finding where the function was called, rather than where it was defined. By searching for onChange in the source code, you can see onChange is called at least 3 times.
this.options.onChange($option, checked);
this.options.onChange($option, true);
this.options.onChange($option, false);
... none of which provide a 3rd argument. I say at least 3 times here, because it can be hard sometimes (particularly in large libraries) to find all call sites, since developers can mask them in all sorts of weird and wonderful ways
Other techniques you can use:
Setting a breakpoint within your handler function (either using the "breakpoint" functionality of your dev. tools, or via the debugger statement), triggering the handler, then following the callstack (again, using developer tools) to examine the call site, and to see what variables are provided.
Opening an issue on the respective GitHub project. You'll find plenty of library owners are more than happy to help.

Unfortunatly, all Javascript libraries must have a very robust documentation.
Moreover, Javascript is a dynamically typed language, so there is no informations about the required types for the formal parameters. It make libraries more difficult to understand without good documentation.
In order to quickly understanding, with experience, there is some thinking mecanisms which can be used. For example, the parameters of an event's delegate provide informations on the elements on which it occurs. It's like these parameters are values returned to you.
In your example, there is chance that option, checked and select are concerned by the option's element in the multiselect defined in #example-onChange which was changed (onChange).
Example 1 :
onClose:function(success)
{
//TODO
}
In this case, "success" should mean : this parameter is true if closing on my element has succeeded else "success" is false.
Example 2 :
afterSave:function(success, filename)
{
}
In this case, "filename" should be the filename of the saved element after perform save's action.
I doing my best for writting correct english, I hope it's understandable.

Related

Trying to determine the meaning of "event.target.contains===this.node"

I'm working on some React stuff, and I found this relevant codepen to my work. Looking through their source code, they used some syntax I'm unfamiliar with.
Specifically, this line in the _handleClick function confused me:
const wasOutside = !(event.target.contains === this.root);
In the context of the code, it's checking to see whether or not the user has clicked outside of a context menu that was generated with a right click. I under stand what it's doing, but I'm unclear on how it's doing it. I've tried to track down documentation on event.target.contains, but I've had no luck.
Here's what I think is happening. Event.target gives me a node location. This.root is also a node location on the dom. I think that event.target.contains is the same as node.contains, but per my reading of the documentation, I think that node.contains could only return a boolean true or false, and it would take an argument of some sort? So far as I can tell, there's no way for wasOutside to have any value except for true, and this code is unnecessary. Is this accurate? Am I missing something, or interpreting something incorrectly?

Javascript: finding a function's code

This is one of the first time's I'm looking at javascript, so please excuse the newbish question.
I'm trying to read the code for a specific function on a website that is of interest to me. I didn't write anything for the website, so cannot really comment on the general structure. This is almost like reverse engineering. Where it's called (in a js/main.js) looks like:
$(document).ready(function() {
$('#search').funcA();
From what I understand this is saying from the file/class or whatever that comesf rom the id search, call funcA. My questions is: how do I see the file that is called with #search?
funcA is almost certainly a jQuery plugin (or part of jQuery itself). The first thing I would try in your situation is searching for "jQuery funcA" on Google.
Whether or not it is actually part of jQuery, you can see the source for that function by running:
$('#search').funcA
in a REPL, such as your browser's console, or:
console.log( $('#search').funcA );
as long as the toString function for that function hasn't been overwritten and it is not a reference to a native function.
funcA appears to be defined as a jQuery method; try
console.log($.fn.funcA)
Open javascript console in the same browser window (I used chrome) that is displaying the page that contains that code. Then just execute this line:
> $('#search').funcA
You should see the body of funcA. Random example output when I did $("#myownid").show:
function funcA (a,b,c){var d,e;if(a||a===0)return
this.animate(cu("show",3),a,b,c);for(var
g=0,h=this.length;g
...
If you manage to see the body of the function, you should be able to infer likely sources (or post them here and we should be able to point you further)
The console.log suggestions here are nice use of Function.prototype.toString (and in some browsers some console magic), but I'd use debugger instead. Chrome has quite nice debugging tools for stuff like this and the debugger statement will get you there with ease.
var test = $('#search').funcA;
debugger;
Open the console and start investigating. When the execution of your code hits that breakpoint, you'll see handy tools like this
Right-clicking test there should also give you the option to "Show function definition" which will show you where the function was actually defined as source code.
And if you want to investigate even further from there, you can always set similar breakpoints right from the Chrome dev console.
Short version: Open the console and run $("#search") it will return a jquery object containing the dom node that has an id of search.
Long version:
$("something")
Is jquery (a java script library) for select elements by css selector returning a jquery object.
https://learn.jquery.com/using-jquery-core/selecting-elements/
$(document).ready(function() {
Is jquery for when my document (basically the page) is ready for me to muck with run this anonymous function.
https://learn.jquery.com/using-jquery-core/document-ready/
$('#search').funcA();
Selects a set of elements, in this case the single element with id "search" and then run funcA on each of them using the element as the scope. So it would run funcA on the element with ID "search" with the search node being the value of the special scope variable (scope is referenced through the key word "this", it can get rather complex).
So in essence what your seeing is:
When my document is ready find the search element and run my function funcA on it.

need suggestions for iterator function in javascript dom generator

am getting rid of all innerHTML and moving to strictly generated dom. reason below. have written a simple dom generator written in javascript that saves me a lot of work and keystrokes.
the big problem I'm having is how to implement an iterator. I feel like it should spit out a series of objects, sort of like a pipe, that the enclosing environment would process, but not much joy integrating the function. here is an example of my current solution
var div = E.div( '.myClass', 's.whiteSpace:nowrap',
'iterator': {
'set': { 'egg':'Scrambled Eggs', 'beer':'Chang Beer', 'yams':'Sweet Potatoes' },
'function':function(v,l) { return E.radio({'name':'myRadio', 'value':v},l); } } }
);
generates a div with three radio buttons. the iterator functionality inside E.div pulls out each value/label pair from the "set" and passes them to the "function", then processes the results of the function - in this case the function makes a radio button.
documentation on the factory plus better examples
http://code.google.com/p/chess-spider/wiki/DomFactory?ts=1302156868&updated=DomFactory
the current version of the javascript is
http://code.google.com/p/chess-spider/source/browse/http/scripts/factory.js
the reason why getting rid of innerHTML (and much raw html): would like the object responsible for the html to generate it as well as handle the triggers for it using closure functions. very big win, and impossible to do with quoted html. this gives the entire functionality contained in a nice "object".
This is more of a pointer. It seems the you can accomplish your task more easily using a JavaScript template engine. Try Handlebars.js and here's a good overview of Handlebars.js Iteration and many other features are available

Unexpected JQuery awesomeness... But how does it work (method missing type syntax)?

Apologies for the vagueness of the title, I can't think of a succint way of summarising this question. I'm new to Javascript and JQuery and needed to respond to a checkbox being toggled, based on its value. Searching the site revealed lots of answers, mostly in the form:
$("input[type='checkbox']").click(function() {
if( $(this).is(':checked') ) {
//code here
}
})
In a flash of dynamic typing inspiration however, I tried typing this into my Javascript console:
$("input[type='checkbox']").click(function() {
if( this.checked ) {
//code here
}
})
...and to my surprise it worked! What's going on here behind the scenes? Is there a method defined called 'checked', or some kind of default property, or even a Ruby-style 'method missing' concept? Is this enabled by JQuery or is it intrinsic to Javascript?
It struck me as pretty awesome and I'd like to understand it better.
This basically boils down to the difference between this and $(this). (Read more here)
this is the DOM object for the current object where as $(this) is the jQuery wrapped version. This means you can do this.checked and is the same as calling normal Javascript.
What this does mean though is that, like #Val said you may run into cross browser issues as you are not relying on jQuery to solve these issues for you.
The reason it works is when the handler is called, its does something to the effect of:
callbackfn.call(<reference to event obj>, .. params .. )
If you go take a look at the JS reference, you'll see that the first parameter passed to .call is the context you want the function to run within. So in this case, since the object passed in is the clicked item, it will be the context.
I disagree with the other replies that this will cause you any trouble in xss browser compatibility, this is how you're supposed to do it and many many jQuery libraries rely on this.
See this stackoverflow article
$(this)[0] == this

Why is dynamically modifying a JavaScript function's code mid-execution a bad thing?

A few days ago, I asked a question regarding dynamically modifying a function's code midway through the outerlying script's execution and I was told to completely forget ever coming upon the notion. I'm not sure I understand why that is. Let me give an example:
<script>
var display = function(msg)
{
alert(msg);
}
// Now, at the moment, the display() function
// is receiving a single parameter and alerting
// it to the user. I'm now going to use eval()
// to modify the display() function.
eval('display = ' + display.toString().replace('alert(', 'document.write('));
// Now, the display() function writes its parameter
// to the document as opposed to alerting it.
</script>
I realize this is a rather trivial example, but there must surely be some use that can be derived from being able to dynamically modify a function, something so useful by itself.
Although this may do what you need it to do, 6 months from now you (or the person maintaining your code) will be going "WTF?!"
If your use case is to alert or write based on some condition, why don't you write two different functions? Or have your function take another parameter that decides the output mode. Or pass in a function as a parameter that performs the actual output. Something, you know, a little more on the sane side. ;-)
There are cases where it could be useful to change a function's behavior, but there are better ways to do it. In your example, you could create new instances of the function that handle the output differently, by passing a function as an argument (similar to the strategy pattern):
function makeDisplay(displayStrategy) {
return function(msg) {
// I'm assuming you would do some additional processing here...
displayStrategy(msg);
}
}
var display = makeDisplay(alert);
// now modify display to use document.write
display = makeDisplay(function(msg) { document.write(msg); });
Well, using eval might be a security concern but modifying a function in real-time is ok. How else you can make memoization anyway?
Although, come to think of it, changing method signature isn't a great idea, other people won't know how to call this function after this, since it would depend on execution order and it's not easy to track usually.
I have found myself needing to do this in situations where I don't have the source code for a particular piece of vendor javascript; so that could be a legitimate use case. I agree that if you have another option, it's better to do it in a more organised way, editing the original function to be more flexible.

Categories