I have been writing javascript for one or two months , I never used Function keyword , like Function.method(); when I define function , I simply define it as :
function fooBar () {};
Can you give me an example when using Function is more convenient ?
You shouldn't use the Function constructor so often, it basically uses code evaluation to build a function.
It requires string arguments, being the last argument the function body, and the previous ones will be the arguments of the new function itself, for example:
var add = new Function("a", "b", "return a + b;");
add(5,5) == 10;
When you should use it?
As I said not so often, I personally try to avoid them since they use code evaluation.
A thing to note is that no closures are created when functions are built in this way, which can be a good thing for some performance circumstances, for example to shorten the process of identifier resolution, but you should use them with care...
Every function in JavaScript is
actually a Function object.
Read Function
Function objects created with the
Function constructor are parsed when
the function is created. This is less
efficient than declaring a function
and calling it within your code,
because functions declared with the
function statement are parsed with the
rest of the code.
function view(){
document.getElementById('one').innerHTML="New Text here";
}
this function can you call from either keyboard events of mouse events
Related
I am learning JavaScript and becoming confused by the logic of the code examples. From codecademy. Why are there function set-ups in function calls?
I'm quite confused. I am moving from a simplified C-like langue.
The JavaScript example
var main = function(){
$('.article').click(function(){
$('.description').hide();
$(this).children('.description').show();
});
};
My understanding:
- main is a function name with a return type of var.
$('.article') is a element/object/or class object.
.click() is a call to a member function
But:
???:
.click(function(){
$('.description').hide();
$(this).children('.description').show();
});
This seems to be a newly on the spot created function to run When/If click() is activated or run.
The way I used to think is like this:
var *p_obj = $('.article');
var *p_obj = $('.description');
var do_click()
{
p_obj2.hide();
p_obj.children(p_obj2).show();
}
var main(){
p_obj.click(do_click);
}
Function main() looks at p_obj and calls click().
Click() evaluates to true/false and run the pointer_to function do_click().
Function do_click() looks at the p_obj2 and calls hide(), which performs an action of hiding the p_obj2.
Function do_click() also looks at p_obj and uses children to scope focus to p_obj2, then it runs show(), which preforms an action of displaying p_obj2.
I do realize my C-like example is wrong and odd. I realize my terminology is wrong or otherwise used incorrectly.
The way this design looks seems like I must write extended functionality on-the-spot for every call to .click(), so if-then .click() is run on 3 different items, I'm creating different extended functionality for each object. But I would normally create a single function that varies it's internal execution based on the object or condition click() calls it by.
This set-up seems alright if the code a relatively simple or short, but on-the-spot functional seems like overworking for longer code and code where the functionality repeats but the objects change.
Am I thinking about JavaScript functions with-in functions correctly and is this a design goal of the langue to add long repeating extended functions with-in functions?
Here, you should understand 2 things:
passing functions as arguments
anonymous functions
The first concept is particulary important because callbacks are popular in JavaScript, so let me explain it for callbacks. Imagine we have 2 functions getStuffFromWeb and processStuff. You probably expect that they are used like this:
var result = getStuffFromWeb();
processStuff(result);
But the issue here is waiting for getStuffFromWeb may take some time (the server is busy), so instead they are usually used in a "when you finish, call this function" manner, which is:
var getStuffFromWeb = function(params,callback) {
...
callback(result);
};
getStuffFromWeb(someParams,processStuff);
Well, in fact the structure of getStuffFromWeb will be different, most likely something like this:
var getStuffFromWeb = function(params,callback) {
requestObject.make_request(params)
.onSuccess(callback);
};
So when getStuffFromWeb is called, it starts to listen to response while the code after getStuffFromWeb(someParams,processStuff); goes on evaluating. When the response comes, it calls the callback function to process the data further using the procedure we have defined (processStuff).
The second concept is rather simple: you may of'course write smth like
var processStuff = function() {...};
var getStuffFromWeb = function(params,callback) {
requestObject.make_request(params)
.onSuccess(callback);
};
getStuffFromWeb(someParams,processStuff);
but if you use processStuff only once, why define a named function? Instead, you can just put the very same expression inside the onSuccess param like this:
var getStuffFromWeb = function(params) {
requestObject.make_request(params)
.onSuccess(function() {...});
};
getStuffFromWeb(someParams);
This looks exactly like if we took the value of processStuff and put it directly to the onSuccess's argument (and that's called anonymous function). And also we got rid of an extra argument of getStuffFromWeb.
So basically that's it.
Simple answer is that the second argument of click() requires a callback function.
This can be a named function passed as reference as in your p_obj.click(do_click); example or it can be an anonymous function with self contained logic. Anonymous functions are very common in javascript
It's the same thing just with 2 different ways of declaring the callback.
Note that the only time you would return anything from an event handler function would be to return false which effectively prevents the default browser event (url opening from href or form submit for examples) and stops event propagating up the DOM tree
main is a function name with a return type of var.
No. main is a variable which is assigned an anonymous function. The function name would go between the keyword function and the () containing the argument list.
It has no return statement so it returns undefined.
$('.article') is a element/object/or class object.
It is a call to the function $ with one argument. The return value is a jQuery object.
.click() is a call to a member function
Pretty much. In JavaScript we call any function that is the value of a property of an object as method.
This seems to be a newly on the spot created function
function () { } is a function expression. It creates a function, exactly like the one used to assign a value to main earlier. This question is worth reading for more on the subject.
When/If click() is activated or run.
The click function is called immediately. The new function is passed as an argument.
The purpose of the click function is to bind a click event handler so that when a click event hits the element later on, it will trigger the function passed as an argument.
I do realize my c -like example is wrong and odd. I realize my terminology is wrong or otherwise used incorrectly.
Leaving aside vagaries of syntax. The main difference here is that the click event handler function is that the event handler function is stored in an intermediary variable.
You can do that in JavaScript just as easily, and then reuse the function elsewhere in the code.
var main = function(){
function show_specific_description() {
$('.description').hide();
$(this).children('.description').show();
}
$('.article').click(show_specific_description);
show_specific_description.call($(".article").last()[0]);
};
main();
is this a design goal of the langue to add long repeating extended functions with-in functions?
No. Passing a function expression as an argument is a convenient way to be more concise when you don't want to reuse the function. It's not the only way to pass functions about.
main is currently a function.
It is possible to be overwritten (even to a different type). var is not the return type, it's a statement that main is a variable.
All values should be declared as variables, within the highest scope you intend them to be used (in JS, scope typically means functions, not blocks).
You have the right idea, suspecting that the function gets passed in, and called at a later point in time (and this is actually one of the harder parts for people to get, coming from certain other languages). You'll see this behaviour all through JS.
One key thing to keep in mind in this language (you haven't hit it yet, but you will) is that JS is lexically scoped.
function getInnerX () {
var x = 5;
function getX () {
return x;
};
return getX;
}
var x = 10;
var getX = getInnerX();
console.log(getX()); // 5
The function getX inside of getInnerX has access to the references around it, at the point where it's defined (not where it's called), and thus has live access to the inner x, even if its value changes over time.
This will be another important piece of understanding what you see going on in the language, especially in the case of callbacks.
Recently I had asked a question
Extract & call JavaScript function defined in the onclick HTML attribute of an element(using jQuery attr/prop)
I needed to programmatically access the onclick attrib of a button which had a function call along with param's in it then supply an extra param & make a function call(onclick=doSomething(2,4)).
But as I figure out that the use of apply/call can also come handy to supply extra param's.For this I extracted the the function name from the attribute & it comes in a string like
arr[1] = 'doSomething';
I tried using Function Constructor to treat this as a function but it doesn't work
(like Function(arr[1])) Why?
Solution mentioned Javascript: interpret string as object reference? works fine. But why it cant be achieved via the function constructor?
Some code info
var funDef ='doSomething'; // this is the name of real function defined in the script
var funcName = new Function(funDef); //expected it to return reference of function doSomething,shows function anonymous() in console
var funcArgs = [5,7,10];
funcName.apply('',funcArgs); //this is the function call.
In this case function does not get called untill I replace
var funcName = new Function(funDef); with var funcName = eval(funDef);
Thanks.
new Function and eval are not interchangeable. When you eval, you are creating code that runs immediately. When you create a Function, that is going to return a function that you can run yourself.
It's almost as if you do:
// This executes 1+2
var resultOfEval = eval('1+2');
// This creates a function that when called, returns 1+2
var resultOfWrappedEval = eval( '(function(){return 1+ 2})' );
// This is much like the line above, you have to call it for it to execute
var resultOfFunctionCtor = new Function('return 1+ 2;');
console.log('resultOfEval', resultOfEval);
console.log('resultOfWrappedEval', resultOfWrappedEval);
console.log('executing resultOfWrappedEval', resultOfWrappedEval());
console.log('resultOfFunctionCtor', resultOfFunctionCtor);
console.log('executing resultOfWrappedEval', resultOfFunctionCtor());
If you show more of your code, we can suggest something, but the key is that when calling the Function constructor, the code doesn't run immediately, it returns a reference to the newly created function.
Also, you seem to understand that you can call the function yourself. What is the problem with doing that?
I discussed this on the JavaScript chat room from where I understood that new Function(..) constructor needs whole function body to return reference in the way I was expecting.
The function constructor does not consider the definition of the doSomething function that is written in the script while eval does.
Other ways that could be fit in this scenarios are here:
Javascript use variable as object name
Comments?
I have the following javascript method:
function 123_test_function(){
}
The function is generated by java and sent to the client. The 123 is the id of the component so it could change. i.e I can have another function called 111_test_function()
I want to pass this function as a reference.
So I need to create the reference
var 123_test_function = function 123_test_function(){
}
In another js file inside an object I have a function that needs to use the 123_test_function reference like so:
useFunction(123_test_function);
The problem I'm having is which the 123 part of the function.
In this object I have a variable(uniqueID) which has the number at the beginning of the function.
I need the function call to be something like:
useFunction(uniqueID+"_test_function");
This doesn't seem to pass a function instead it passes a string.
Am I doing something wrong?
For one, identifiers (such as function names) cannot begin with a digit.
To solve your problem, use an object, like this:
// 1. define an object to hold all your functions
var allFunctions = {};
// 2. store any function with a unique string as the ID
allFunctions['123_test_function'] = function () {
// whatever
};
// 3. call the function
allFunctions['123_test_function']();
allFunctions[uniqueID + '_test_function']();
Objects are associative arrays. They store key/values pairs, so they do exactly what you want here.
Note that functions don't need a name in JavaScript, so I did not use on in step 2.
If the function is defined as global one, it will be a member of global object (window in case of browsers). Hence you can just do window['id_'+uniqueID+'_test_function'] to access your function
useFunction(window['id_'+uniqueID+'_test_function'])
(Identifiers cannot begin with numbers in JavaScript so I added the 'id_' prefix. You can of course change it to your liking.)
function test_function(number){
if(number == 1)
{
return function() {}
}
if(number == 2)
{
return function() {}
}
}
call the function like this
var func = test_function(1)
func();
As a couple of people have correctly pointed out, a function (or indeed variable) name cannot begin with a numeric. Also this syntax is wrong:
var 123_test_function = function 123_test_function(){
}
The correct syntax would be:
var 123_test_function = function() {
};
...although it should also be noted that the effect of this is exactly the same as a "traditional"
function 123_test_function() {
}
...declaration, in the context of the window object - since window is effectively the global scope of a JS environment in a browser, it doesn't matter how you define the functions, they will always be accessible from anywhere. Understanding exactly what each method of declaring a function means in Javascript is important - luckily, Douglas Crockford to the rescue once again...
People have suggested various methods for calling your named functions from the context of a string, which is basically attempting to use "variable variable" syntax, a subject that has been discussed on SO and elsewhere at length. The eval() approach should be avoided wherever possible - if you find yourself needing an eval() chances are you went wrong somewhere a while back. #Tomalak has the right idea with a collection of functions held in an object, but this still needs the slightly messy string approach to reference things that are actually being accessed by a numeric ID. The collection approach has the advantage of not cluttering up the window object with what are likely to be single/zero use members.
But the way I see it, all you actually need here is an indexed array of functions, where all you need is the numeric index in order to access them. I suggest you create your functions like this:
// Do this once at the top of your JS
var test_functions = [];
// Now, for each function you define:
test_functions[123] = function() {
// Do stuff here
};
// And when you need to call the functions:
var funcId = 123;
test_functions[funcId]();
I deal with a JavaScript code to improve.
The idea here is to invoke functions dynamically.
Here is the code to replace:
//this.actionCallback return the name of the function to invoke
eval(this.actionCallback + "('testArgument')");
What is the best way to replace it:
This way:
window[this.actionCallback]("testArgument");
Or this way:
var actionToCall = this.actionCallback+'("testArgument");';
var functionToInvoke = new Function(actionToCall);
functionToInvoke();
Or is there is a better way to do this?
The first way is a much better method - new Function(actionToCall) is just eval in disguise.
Both of the alternatives you have mentioned are not equivalent to the first one:
Your first alternative requires that the function name be the member of window (in other words, defined at global scope). Having a function inside another scope will cause this to fail, but it doesn't use eval. :)
Your second alternative creates a function object using the Function() constructor, so this also only works when the function in declared at the global scope, because a function defined by a Function constructor does not inherit any scope other than the global scope, and as said in Jamie Wong's answer, using the Function() constructor is still considered as eval :(
Here is an alternative that should work like your first one, but looks slightly better, but still uses eval.
eval(this.actionCallback)("testArgument");
But the best way is that this.actionCallback should be a real function object, and not just a function's name, then you can call:
this.actionCallback("testArgument");
I would suggest using window[this.actionCallback]("testArgument");.
This way there is no evaling or making anonymous functions. You are just calling the function directly.
In case like this you probably do not want to allow calling arbitrary functions, only "action" functions.
Build a list of supported callbacks
actionCallbacks["doWork"] = doWork;
Call them
actionCallbacks[this.actionCallback]("testArgument")
And catch if function does not exist
If the function belongs to an object you can do something like this:
function run(func, object, args = []) {
object[func]().apply(object, args);
}
Also, here is unique (but not very reliable) way of replacing eval:
function evaluate(code) {
location.href = "javascript:" + code;
}
evaluate("alert(1)");
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Javascript: var functionName = function() {} vs function functionName() {}
Way 1:
function fancy_function(){
// Fancy stuff happening here
}
Way 2:
var fancy_function = function(){
// Fancy stuff happening here, too.
}
I use the former when I'm just defining a "normal" function that I'm gonna use one or several times and the latter when I'm passing it a callback for another function or so, but it looks to work fine in the both ways.
Is it really a difference in some way?
There is no difference to the function itself, but the latter gives you more flexibility as you have a reference to the function and it is different with regard to how it behaves if overwritten.
This allows you to achieve behaviours with the latter that you cannot achieve with the former; such as the following trick to "override" an existing function and then call the "base":
var myOriginalFunction = function() {
window.alert("original");
}
var original = myOriginalFunction;
var myOriginalFunction = function() {
window.alert("overridden");
original();
}
myOriginalFunction();
This gives you an alert "overridden", followed by an alert "original".
However, if you attempt this with the former notation, you'll find you get stuck in a never ending loop of alert "overidden".
In the first sample you are defining a named function -- that function will always be known by that name. Defining a different function with the same name will be an error (unless you assign to the window property directly). In the second sample, you are defining an anonymous function and assigning it as the value of a variable. You can change the value of the variable to any other function later as desired; losing, of course, any reference to the anonymous function in the process unless you've stored it elsewhere. So, you're not really doing the same thing in both cases, though you can treat it that way if you wish -- and make sure to define the function before it's used in the second case, though that's more a function of variables than functions per se.
function definition
function literal assignment
only difference is you can access the former instantly in certain cases whereas you have to wait for the assignment on the latter.
Don't run this in firebug console/interpreter to test it, rather test on a real html page.
say('spotted');
function say(msg){ alert(msg) }
The above will work, but if you defined a function literal with var say = function(){} below, it would complain that it isn't defined yet.
You can use either depending on the situation, both become the methods of the window object. The later is known as anonymous function.
As far as the function is concerned, they will behave identically.
See here for more details: http://javascript.about.com/library/blfunc.htm
Functions defined with the Function(){} style are available throughout the program, without having to be defined earlier in the code than where they are called. It's called 'hoisting', I believe.
so this works
cow('spotted');
function cow(color){ return 'cow is '+color; }
but this throws an error
cow('spotted');//cow isn't defined yet!
var cow=function(color){ return 'cow is '+color; }