Calling vs invoking a function - javascript

Up to this point, I thought "calling" and "invoking" a function meant the same thing. However, in a YouTube tutorial it said to invoke a function by calling it. My first thought was that the wording was a mistake, but on W3Schools' page on Function Invocation, it says:
It is common to use the term "call a function" instead of "invoke a
function" ... In this tutorial, we will use invoke, because a
JavaScript function can be invoked without being called.
Okay, so there's a difference. What is it?

Your reference text:
It is common to use the term "call a function" instead of "invoke a
function" ... In this tutorial, we will use invoke, because a
JavaScript function can be invoked without being called.
Now let me rephrase it:
It is common to use the term "call a function" instead of "invoke a
function" ... In this tutorial, we will use the term invoke instead of call, because a
JavaScript function can be invoked indirectly like fn.call() and fn.apply() without being called directly like fn().
So, when I do fn(), it's invoked directly and when I do it like fn.call(), it's invoked indirectly but in both cases, the function is being invoked. Otherwise, I see no difference here and I can also say that I can call a function in many ways, for example:
fn(); // I'm calling it
fn.call(); // I'm calling it
fn.apply(); // I'm calling it
So, the difference is semantic but both are interchangeable, IMO. BTW, I wrote a comment above, under the question and I would like to put it here, which is:
IMO, that's a misleading statement. Maybe there are some indication of
call/apply or something else but it's totally confusing.

The difference is semantic and subtle. When you call a function, you are directly telling it to run. When you invoke a function, you are letting something run it.
There is one way to call a function:
myFunction()
Here, you are invoking the function (letting it run) by calling it directly.
There are many ways to invoke a function (given throughout different comments and answers). Here's one example:
function invoker(functionName) {
functionName()
}
invoker(myFunction)
Here, by calling invoker, you are invoking myFunction, which is being called indirectly.

Yes, in most cases we use both to refer the execution of a function.
There are 2 ways to reach place B from your HOME.
Direct/Automatic way (Invoke), i.e. if you choose first way, you do not need to walk. Someone will automatically take you to place B.
Indirect way (Call), i.e. if choose second way, you only need to reach A(by walk). Someone is there at place A to automatically take you to place B.
Have a look at the below image. I think it will clear your doubt.
In case of Calling, you originally refer to the statement that actually calls the function.
In case of Invoking, you indirectly refer to calling statement to actually invoke/run the function.

Many people use the term calling and invoking interchangeably but that's not right. There is a very slight difference between calling and invoking a function. In JavaScript functions can be invoked without being called which means that the code inside the body of the function can be executed without creating an object for the same. It is tied to the global object. When there is no individual object, the value of this is associated with the global object.
There is also a difference between call and apply, the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments. A different this object can be assigned when calling an existing function. this refers to the current object, the calling object. With call, you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.
So, the major difference between invoking and calling comes in terms of the this object. Calling let's you set the this value whereas invoking just ties it to the global object.

"function invoked" means a function got executed
"function called" means that a function was called by another function and then executed
"function invoked without being called" is a function that got self invoked without being called by another function
example of a self invoking function calling another function:
var f = (function() {
foo();
})(); ///() here means it self invoked -- without being called directly.
var foo = (function() {
///Do something here
});

Related

Uncaught (in promise) TypeError: stringConcat() is not a function : Async String Concatenation doesnt work [duplicate]

I have the following function
function hello() {
alert("hi!");
}
Take this piece of code:
var elem = document.getElementById("btn");
elem.onclick = hello;
My question might be a bit hard to understand, so bear with me:
What EXACTLY differentiates THIS piece of code from a normal call, or what makes this piece of code require a reference to the function variable rather than a regular call? (hello();)
How can I know where I'm supposed to give a reference to the function, and when I'm supposed to actually call it?
Well, the onclick property expects a reference to a function, for it to execute when the element is clicked. Normally it's either:
element.onclick = funcRef;
or
element.onclick = function () {
funcRef();
};
(but of course, it's best to use addEventListener and attachEvent)
Notice how both of them are references to functions, not calling.
When something expects a reference, you don't call it...you assign a reference to it (first example).
When you want to specifically call a function, you call it with () (second example). But notice how in the second example, there's still a reference to a function that's assigned to onclick - it's just an anonymous function.
Probably the more important part:
Some people think you want to do this:
element.onclick = funcRef();
But that immediately executes the function (because of the ()), and assigns its return value to onclick. Unless the return value is a function, this isn't what you want.
I think the moral of the story is that when you want/need something to execute right now, you call the function. If the function is wanted for later use or needs stored, you don't call it.
Do you want it to execute NOW? Then call it.
a=hello() means "Call hello() ASAP, and set its return value to a".
On the other hand, a=hello means "a is an alias for hello. If you call a(), you get the same results as calling hello()"
You use the latter for callbacks, etc, where you want to tell the browser what you want to happen after an event occurs. For example, you may want to say "call hello() when the user clicks" (as in the example). Or, "When the AJAX query returns a result, call the callback() function on the returned data".
How can I know where I'm supposed to give a reference to the function, and when I'm supposed to actually call it?
Do you need the function to run now?
Than add the () to execute it
Do you need to function to be referenced so it is called later?
Do not add the ().
Pretty much all statements in JavaScript have a return value. Unless otherwise specified, functions in JavaScript will return undefined when called. So, the only context in which it would make sense to call your function in this assignment statement if it were to return a function:
function hello() {
return function() {
alert("hi!");
}
}
elem.onclick = hello();
A reference to your function is needed somewhere no matter how it gets called. The difference here is that you are not explicitly calling the hello function. You are assigning a reference to that function to the elem DOM node's onclick event handler so that when onclick is fired for that Node, your function gets called.
hello() means you call that function, which means the function will be executed directly.
while when you have elem.onclick = hello, this is called a callback. Where hello doesn't get executed directly but only when a certain event is fired (in this case when there's a click on the element)

Is this.someFunction.bind(this) redundant?

I'm reading someone's code and I see the following:
this.device_name.changes().onValue(this.changeName.bind(this))
From what I understand, onValue takes a callback function, and that function is this.changeName.bind(this)). Correct me if I'm wrong:
The default value of this in a function call refers the object with which the function was called upon.
The .bind(someObject) method causes the function's this to refer to someObject instead, when the function gets executed.
Knowing this (heh), this.changeName.bind(this) seems redundant: the default value for this when calling this.changeName will be the same this that is passed in the bind parameter.
So! Can the function be safely refactored to simply this.changeName with no differences in behavior?
No, the bind is very important here.
A function's this pointer is set at the time the function is called. The call, in this case, is down inside whatever object is invoking the callback. Many objects just call with a this pointer either as null or (in the case of DOM objects) pointing to the DOM object itself.
Using the bind function this way returns a new function that hard-wired the this reference to the value passed to bind. If you take out the bind, it'll completely hose up the this pointer. It will DEFINITELY change the behavior.

why is it necessary to wrap function call in a function body

I often see something like the following in JavaScript:
$("#sendButton").click(function() {
sendForm();
}
Why is it necessary to wrap the call to sendForm() inside a function? I would think that doing it like this would be more readable and less typing.
$("#sendButton").click(sendForm);
What are the advantages/disadvantages to each approach? thanks!
There's typically two cases where you'd want to use the former over the latter:
If you need to do any post-processing to the arguments before calling your function.
If you're calling a method on an object, the scope (this reference) will be different if you use the second form
For example:
MyClass = function(){
this.baz = 1;
};
MyClass.prototype.handle = function(){
console.log(this.baz);
};
var o = new MyClass();
$('#foo').click(o.handle);
$('#foo').click(function(){
o.handle();
});
Console output:
undefined
1
Probably one too many answers by now, but the difference between the two is the value of this, namely the scope, entering sendForm. (Also different will be the arguments.) Let me explain.
According to the JavaScript specification, calling a function like this: sendForm(); invokes the function with no context object. This is a JavaScript given.
However, when you pass a function as an argument, like this: $(...).click(sendForm), you simply pass a reference to the function for later invocation. You are not invoking that function just yet, but simply passing it around just like an object reference. You only invoke functions if the () follows them (with the exception of call and apply, discussed later). In any case, if and when someone eventually calls this function, that someone can choose what scope to call the function with.
In our case, that someone is jQuery. When you pass your function into $(...).click(), jQuery will later invoke the function and set the scope (this) to the HTML element target of the click event. You can try it: $(...).click(function() { alert(this); });, will get you a string representing a HTML element.
So if you give jQuery a reference to an anonymous function that says sendForm(), jQuery will set the scope when calling that function, and that function will then call sendForm without scope. In essence, it will clear the this. Try it: $(...).click(function() { (function() { alert(this); })(); });. Here, we have an anonymous function calling an anonymous function. We need the parentheses around the inner anonymous function so that the () applies to the function.
If instead you give jQuery a reference to the named function sendForm, jQuery will invoke this function directly and give it the scope that it promises to always give.
So the answer to your question becomes more obvious now: if you need this to point to the element target of the click when you start work in sendForm, use .click(sendForm). Otherwise, both work just as well. You probably don't need this, so skip the anonymous function.
For those curious, scope can be forced by using the JavaScript standard apply or call (see this for differences between the two). Scope is also assigned when using the dot operator, like in: obj.func, which asks of JavaScript to call a function with this pointing to obj. (So in theory you could force obj to be the scope when calling a function by doing something like: obj.foo = (reference to function); obj.foo(); delete obj.foo; but this is a pretty ugly way of using apply.
Function apply, used by jQuery to call your click handler with scope, can also force arguments on the function call, and in fact jQuery does pass arguments to its click handlers. Therefore, there is another difference between the two cases: arguments, not only scope, get lost when you call sendForm from an anonymous function and pass no parameters.
Here you are defining an anonymous event handler that could call multiple functions inline. It's dirty and tough to debug, but people do it because they are lazy and they can.
It would also work like your second example (how I define event handlers):
$("#sendButton").click(sendForm)
Something you get by defining your event handlers inline is the ability to pass event data to multiple functions and you get this scoped to the event object:
$("#sendButton").click(function(event) {
sendForm();
doSomethingElse(event);
andAnotherThing(event);
// say #sendButton is an image or has some data attributes
var myButtonSrc = $(this).attr("src");
var myData = $(this).data("someData");
});
If all you are doing is calling sendForm, then there isn't much difference, in the end, between the two examples you included.
$("#sendButton").click(function(event) {
if(event.someProperty) { /* ... */ }
else { sendForm({data: event.target, important: 'yes'}); }
}
However, in the above case, we could handle arguments passed to the callback from click(), but if the sendForm function is already equipped to handle this, then there's no reason why you wouldn't place sendForm as the callback argument if that is truly all you are doing.
function sendForm(event) {
// Do something meaningful here.
}
$("#sendButton").click(sendForm);
Note that it is up to you where you handle the differing layers of logic in your program; you may have encapsulated certain generic functionality in a sendForm function then have a sendFormCallback which you pass to these sorts of function which handle the interim business of event/callback processing before calling sendForm itself.
If you are working in a callback-heavy environment, it would be wise to separate significant functionality from the callback triggers themselves to avoid callback hell and promote maintainability and readability in your source code.
It's just to lock scope. When you wrap that sendForm() in the anonymous function that closes over the current scope. In other words, the this will be kept with it. If you just pass sendForm then any calls to this will come from the calling scope.
This is a good question for learning about scope in javascript, and questioning conventions.
Nope, that second example is perfectly valid.
99.9% of jQuery examples use the first notation, that doesn't mean you need to forget basic JavaScript syntax.

Is it good to write javascript functions inside functions and not use 'new' on the main function?

I now know this works:
function outerfunction(arg1, arg2, arg3) {
var others;
//Some code
innerFunction();
function innerFunction() {
//do some stuff
//I have access to the args and vars of the outerFunction also I can limit the scope of vars in the innerFunction..!
}
//Also
$.ajax({
success : secondInnerFunction;
});
function secondInnerFunction() {
// Has all the same benefits!
}
}
outerFunction();
So, I am not doing a 'new' on the outerFunction, but I am using it as an object! How correct is this, semantically?
There doesn't appear to be anything wrong with what you're doing. new is used to construct a new object from a function that is intended as a constructor function. Without new, no object is created; the function just executes and returns the result.
I assume you're confused about the closure, and how the functions and other variables belonging to the function scope are kept alive after the function exits. If that's the case, I suggest you take a look at the jibbering JavaScript FAQ.
You are not using the outer function as an object. You are using it to provide a closure. The border line is, admittedly, thin, but in this case, you are far away from objects, since you do not pass around any kind of handle to some more generic code invoking methods, all you do is limiting the scope of some variables to the code that needs to be able to see them.
JFTR, there is really no need to give the outer function a name. Just invoke it:
(function() { // just for variable scoping
var others;
...
})()
I do this sort of thing all the time. Yes - javascript blurs the boundary between objects and functions somewhat. Or perhaps, more correctly, a javascript function is just an object that is callable. You would only really use the 'new' prefix if you wanted to have multiple instances of the function. My only suggestion here is that its usually considered good practice to call a function after you've declared it (you are calling the innerFunction before it has been declared) - although that could be considered nit-picking.
This is a valid example.
Functions in JavaScript are first order objects. They can be passed as an argument, returned from a function or even set to a variable. Therefore they are called 'lambda'.
So when you are directly using this function (without new keyword) you are directly dealing with the function as an object. When u are using new keyword, you are dealing with an object instance of the function.

In javascript, how can I tell what object a function is bound to (ie, its 'this') without calling it?

Does anybody know? Couldn't find this question asked before, even though it seems fairly basic.
The context (the this keyword) it's not completely implicit, it can be set and changed explicitly.
For example:
function test () {
alert(this);
}
test.call("Hello world");
The test function is called with a string as the context.
So in conclusion, you cannot know what this is unless you explicitly define it, or you are inside the function.
The same function will see different values of this depending on how it called. See Crockford for details, but there are four cases:
Invoked as a simple function, it is bound to the global/window object.
Invoked as a method on an object, it refers to that object.
Invoked as a constructor via the new keyword, it is the newly instantiated object, which inherits from the object stored in function's own prototype property.
Invoked by its own apply or call method, it is the first argument supplied.
If these cases sound complex, tedious, and error-prone, all the more reason to avoid relying on this outside of methods, where it makes the most sense anyway.

Categories

Resources