understanding javascript function call and referance - javascript

I found this browsing:
What is the difference between a function call and function reference?
After reading the answers there, I did't understand the definition and usage for function references and function calls. Then I searched a lot, but it is still unclear where to use what.
Could you help me understand this by pointing out the differences in concept and usage? I want to make this as a reference for future programers.

Take this for example:
function foo() {
alert('foo');
return 'bar';
}
First of all, what is a function? It's a routine that can be called (or "invoked", or "executed"), and when you do so it usually does something, and returns some value.
So you have a function named foo. You can call it by adding () after its name:
foo();
You can store the return value in a variable, if you assign the result of the invocation to it:
var something = foo();
something === 'bar'; // true
But that's not all you can do with functions in JavaScript. It's a language where functions are first class citizens, so they can be passed around to other functions, and returned from other functions. They can also be stored as variables. For example:
var refToFoo = foo;
Now refToFoo is the same as foo. It's not a copy, it's a reference pointing to the same (internal) function object as foo. So you can use refToFoo just like you would use foo:
var something = refToFoo();
something === 'bar'; // true
refToFoo === foo; // true; they're the same object
Perhaps the most common use to function references is to use them as event listeners:
someElement.onclick = foo;
Note there is no parentheses above. It we used parentheses, foo would be invoked, immediately, and its return value would be assigned to the element's onclick method. Since that function returns a string, nothing would happen if the element were clicked. That's a very common mistake newbies do. Another common one is invoking a function instead of passing a reference to setTimeout:
setTimeout(foo(), 1000); // WRONG - foo is executed immediately
Compare that to:
setTimeout(foo, 1000); // RIGHT - we're passing a reference to the function,
// that will be invoked by the js engine after 1000ms
I hope this helps clarify your doubt.

Related

whats the difference between closures and this

I am just getting more into javascript and wandering what is the difference between
var myfunc = function(){
publicfunctions = {}
publicfunctions.function1 = function(){do smthing and return}
return publicfunctions
}
and
var myfunc = function(){
this.function1 = function(){do smthing and return}
}
It seems to me that both doing the same thing
Also can someone explain what is difference between
var func = (function myfunc(){ .. do smthing and return .. })();
and
var func = function myfunc(){ .. do smthing and return .. }
var newfunc = new myfunc()
Thanks
Let's go step by step.
example:
a) you define a function that returns an object (careful with variable declaration - you should declare it with var keyword in order to scope it to your function. That objects has a single property that points to a function. Never the less, your first function is assigned to a variable myfunc
Now, if you try to call myfunc(), you'll get an object with single property function1. Nothing special here.
b) you define a function again and assign it to myfunc variable, only this time it contains this keyword which assumes you're trying to utilize this function as a constructor. In this example, merely calling myfunc produce no output since you haven't returned anything from a function. However, calling a function with preceding keyword new will result in object creation.
var myObj = new myfunc();
// `this` keyword now refers to myObj which means myObj can call `function1`
example:
a) On the righthand side is something that is called IIFE (or Immediately Invoked Function Expression). Basically means, a function expression that is created and executed, well, immediately. So func should receive whatever that function returns.
b) Yet again, facing a constructor, only this time you actually assumed myfunc is a constructor when you added new keyword before myfunc execution. Creates an object to whic newfunc now points to and has authority over.
Note:
In constructor functions (the ones that you call with new keyword), this is implicitly returned and no need for explicit return. Now, if you want to test it and return something else instead, I'll leave it up to you to explore and see what you'll end up with. :)
Since it's a broader topic in itself, I recommend this excellent book by Nicholas Zakas. It really answers a lot of JS questions.

What is going on inside the $.each()?

I am stumbling upon a problem that I have seen before, but that I couldn't solve before. I will likely stumble upon it again in the future, so please, someone explain it to me what is going on?
In the partial snippet of javascript below, I have a function that populates a screen, including an order combobox (twitter bootstrap). When I click on one of the order items in that combobox, it should invoke the function clsModCampaigns.blnCompaniesListReload().
For a reason that I don't understand, once inside the '$.each' iterator, the global object reference 'objModCampaigns' is lost? I get a successful alert '1', but not an alert '2'.
Within the $.each, I would like to use 'objModCampaigns.arrOrderBy' instead of 'this.arrOrderBy', but the $.each iterator only seems to work this way. Why is it working this way??
What is going on with 'this', or with variables/objects assigned in the root of the class with 'this'?
Is $.each just special??
function clsModCampaigns(objSetSystem, objSetModuleBase)
{
objModCampaigns = this;
arrOrderBy = {
intID: 'ID',
strName: 'Name'};
[...]
this.blnScreenCampaignInitialize = function (fncSuccess,fncError, intID) {
$.each(this.arrOrderBy, function (strFieldName, strFieldDescription) {
if(strFieldName != 'datDeleted' || objSystem.blnHasPerm("CAMPAIGNS_DELETED")) {
strOrderByID = "ulCampaignsCompaniesListOrderBy" + strFieldName;
$("#ulCampaignsCompaniesListOrderBy").append('<li>'+strFieldDescription+'</li>');
$("#"+strOrderByID).unbind("click").bind("click", function() {
alert("1");
objModCampaigns.arrCurrentShownCompanies.strOrderBy = strFieldName;
objModCampaigns.blnCompaniesListReload();
alert("2");
});
}
});
return true;
};
}
The code you have is
$.each(this.arrOrderBy, ...);
You want
$.each(arrOrderBy, ...);
The reason for it is the this context on that line is different because it is inside a new function this.blnScreenCampaignInitialize.
This is just a part of how JavaScript works
var message = "hello";
function welcome() {
console.log(message);
}
welcome(); // "hello"
P.S. use var
If you don't use var, you'll be attaching all of your vars to the global object.
function hello() {
foo = "bar";
console.log(foo);
};
hello(); // "bar"
console.log(foo); // "bar"
// Holy smokes! `foo` has escaped our `hello` function!
Compare that to
function hello() {
var foo = "bar";
console.log(foo);
}
hello(); // "bar"
console.log(foo); // ReferenceError: foo is not defined
// much better
Now let's see a terrible example
function a() {
b = 5;
return b;
}
function b() {
return "function";
}
console.log(a()); // 5
console.log(b()); // TypeError: number is not a function
This is happening because we didn't use var properly. We first define b as a function but after running a(), b is now set to 5. The second log statement is the equivalent of trying to run 5() because b is no longer a function.
P.P.S. it's pretty unconventional to prefix your vars with str, int, fnc, obj, or cls in JavaScript.
I understand you're a "VB guy" according to your comments, but that's no excuse for bringing your own conventions to the language. I see in your profile that you're fluent in Dutch, English, German, and French. I would recommend you treat learning programming languages much the same as spoken languages: each of them have their own explicit set of rules and conventions.
Here's a heap of free JavaScript books for you. I hope they can help you learn some more basics.
P.P.P.S. Overall, your function is really big as it is, and I can see you already truncated some of the code with your [...]. The whole thing could probably benefit from some better composition.
If you paste all of your code, maybe someone could help you better.
What is going on inside the $.each() ?
Regarding you question title, I'm trying to answer:
// each function in source
function (obj, callback, args) {
//...
}
Check the source of complete $.each function by yourself, you can see any function's source code just by typing the function name in the appropriate text box (the second on top).
Here in each function, the array/object passed in to the each function (the first argument) is being run through a loop and each value is being passed in to the callback (second argument) and that call back is getting executed like:
callback.apply(obj[i], args);
So, the passed callback in the each function is being executed each time the loop occurs ad the current value in the loop is passed as the argument of callback function along with the third argument args.
If your function function clsModCampaigns(){ //... } is a normal function then this inside this function points to global window object. so just use:
$.each(arrOrderBy, ...);
instead of
$.each(this.arrOrderBy, ...);
Because, arrOrderBy is within the direct scope so arrOrderBy is accessible directrly. For example:
function someThing()
{
var x = 'y'; //<-- this scope (everything inside someThing) is
// global for somethingElse inner function
function someThingElse)(x) //<-- possible to use directly
{
}
}
The keyword this behaves differently depending on the context. Check about this on MDN.

What is the purpose of a function call a function itself as foobar.call(foobar)?

I had a question when reading a source code. The code example is as below:
// ... some code omitted
function p() {var u=new i();this. $Arbiter0=new s(); this.$Arbiter3=[];}
p.prototype.subscribe = function() { ... }
p.call(p) // <-- what is the purpose of this statement?
I'm new at JavaScript. I read from textbook that, when you use Function.call(Function), it usually means borrow inganother function constructor, in order to do some code-reuse/inherit stuff. BUT, I'm not sure what the purpose of doing it in this code example, i mean, the function is calling the function itself?
Clarify:
I know the use of Function.call(). I just want to know, what is the benefit of doing foobar.call(foobar)?
====
The complete source code is as below:
https://fbstatic-a.akamaihd.net/rsrc.php/v2/y6/r/USEL5meM70H.js
Search 'p.call(p)' in that source code. There is only one occurrence in that file.
====
Thank you.
p.call(p) has the effect of calling the function p, such that the value of this, within the function body, is the function itself.
This allows you to add properties to the function from within the function.
Relevant documentation for Function.call can be found here.
Since this is minified code, it's possible that this construct is an artifact of the minification process. It seems that the intent here is to initialize p; it's probably setting up data structures for storing subscribers.
The first argument for the .call is the element that will be used as this in the executed function.
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
You know in JavaScript, functions are also Objects. That means you can have method and properties associated to functions.
For example :
I can create a function called foo and add a property to it like below
function Foo(){};
Foo.bar = [1,2,3,4,5];
Foo.sayName = function(){ alert("hi Tom")};
This methods are called as static methods ( Classical OOP pattern: function constructor act like a class in javascript ), so that you don't need to instantiate an Object of Foo to access sayName method.
Coming back to the actual question. What happens when you do Foo.call(Foo);
The call method expect an object as the first parameter, and invoke the function on which it's called. When the function is invoked, this pointer will be pointed to the object passed. In this case, it's the Foo function ( Object ) itself.
Assume that if Foo function is written this way
function Foo(){
this.bar = [1,2,3,4,5];
this.sayName = function(){ alert("hi")};
}
After executing Foo.call(Foo), you can see that the actual Foo function ( Object ) will have the properties bar and method sayName got added.
I guess the script which you have sent is doing that to reduce code duplication.

Accessing variable in callback function... what?

I've been through a ton of posts and I finally got what I needed thanks to this:
$("a.foo").click(function(){
var that = this;
jPrompt("Type something:","","", function(r) {
$(that).text(r);
}
}
From the following:
Accessing $(this) within a callback function
I was wondering if someone could expand on what exactly is happening here (why is this not available without re-assigning?) and what core information I should read up on? From what I gather this might have something to do with closures... that's most of what I bumped into while searching around. Is that accurate?
In my case, I was looking to execute some code, then redirect once an ajax request completed. In the callback function I was running $(this).attr("href") which was returning undefined.
this is assigned by javascript according to how a function is called. So, it is the jPrompt() function that determines what value this will have in your callback when jPrompt() calls the callback.
So, unless jPrompt goes out of its way to keep the same value for this via some argument you passed in, it will likely have a different value. As such, you can save it away for access within the callback as you've done. This is a very common design pattern in javacscript callbacks.
FYI, some of the ways that this is assigned:
obj.method() - this in method() will be set to obj
func.call(obj) - this in func() will be set to obj
func() - this will be set to window in func() or undefined in strict mode
The meaning of this changes depending on where you're at. The this within a handler for your click event means something other than the this within the callback passed to your jPrompt function.
For what it's worth, you don't need to re-assign this, since the event object passed into your handler will have a reference to the currentTarget:
$("a.foo").on("click", function (event) {
// 'this' here refers to the anchor we clicked
jPrompt("Type something:", "", "", function (r) {
// 'this' here refers to whatever jPrompt instructs
$(event.currentTarget).text(r);
}
}
The code in the question with some added comments:
$("a.foo").click(function(){
var that = this; //`this` holds the a object clicked. now so does `that`!
jPrompt("Type something:","","", function(r) {
//even if `this` has a different value here, `that` still holds the a object clicked
$(that).text(r);
}
}
This is something you will often find yourself doing in similar situations. this is context-dependent and you often need to keep the value this had in one context and use it in another.
A quote from the ECMAScript specification:
10.1.7 This
There is a this value associated with
every active execution context. The
this value depends on the caller and
the type of code being executed and is
determined when control enters the
execution context.
Hope that answers your question. You also asked for a resource for further reading. Please visit:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this
These guys provide excellent documentation both detailed and typically quite accurate (unlike other popular sources of reference that often comes first in Google searches -- w3cshools.com I am thinking of you!).
A Short Overview of this
this in JavaScript is dynamically scoped. Its behavior differs from all other variables which are lexically scoped. Other variables don't have a different binding depending on how the function is called; their scope comes from where they appear in the script. this however behaves differently, and can have a different binding depending not on where it appears in the script but on how it's called. Consequently, it can be a source of confusion for people learning the language, but mastering it is necessary in order to become a proficient JavaScript developer.
Since this is dynamically bound there are several ways to change its values based on how you call the function.
Examples
When you execute a function in JavaScript, the default this is window.
function foo() {
console.log(this);
}
foo(); // => window
The this value can be changed in a number of ways. One way is to call the function as a method of an object:
var x = {
foo: function() {
console.log(this);
}
};
x.foo(); // => This time it's the x object.
Another way is to use call or apply to tell the function to execute in the context of a certain object.
function foo() {
console.log(this);
}
foo.call(x); // => x object again
foo.apply(x); // => x object as well
If you call or apply on null or undefined, the default behavior will occur again: the function will be executed in the context of window:
function foo() {
console.log(this);
}
foo.call(null); // => window
foo.apply(undefined); // => window
However, note that in ECMAScript 5 strict mode, this does not default to window:
(function() {
'use strict';
function foo() {
console.log(this);
}
foo(); // => undefined
foo.call(null); // => null
foo.apply(undefined); // => undefined
})();
You can also set the this by using bind to bind the function to an object before it is called:
function foo() {
console.log(this);
}
var bar = {
baz: 'some property'
};
var foobar = foo.bind(bar);
foobar(); // => calls foo with bar as this
Going Father: Lazy Bind / Uncurrying this
Going further, you may sometimes want to take functions which act on a this and allow the this value to be passed in as the first argument to the function. This can be really helpful for Array methods, such as forEach. For instance, let's say you are dealing with an object which is array-like but not actually an array.
var arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
'length': 3
};
If you want to iterate over this object with forEach, you could use call:
Array.prototype.forEach.call(arrayLike, function(item) {
console.log(item);
});
// Logs: a, b, c
However, another option is to create a forEach function which can be called directly on your object:
var forEach = Function.prototype.call.bind(Array.prototype.forEach);
Now you can use this function anytime you want to iterate over an array-like object:
forEach(arrayLike, function(item) {
console.log(item);
});
// Logs: a, b, c
Sometimes this method is referred to as "uncurrying this". However, I prefer to create a function which can generate these "uncurried" functions and call it "lazy binding".
var lazyBind = Function.prototype.bind.bind(Function.prototype.call);
var forEach = lazyBind(Array.prototype.forEach);
var slice = lazyBind(Array.prototype.slice);
var map = lazyBind(Array.prototype.map);
forEach(arrayLike, function(u) {
console.log(u);
});
// Logs: a, b, c
var realArray = slice(arrayLike);
// Converts arrayLike into a real array
forEach(
map(arrayLike, function(u) {
return u + 'Q';
}),
function(u) {
console.log(u);
}
);
// Logs: aQ, bQ, cQ
One really awesome thing about this technique is it can be useful for creating securable JavaScript, which can be helpful if you don't want other scripts on the page snooping around your internal variables. This is a pretty advanced meta-programming technique, though, and you don't see it in day-to-day JavaScript.

Advanced JavaScript: Why is this function wrapped in parentheses? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the (function() { } )() construct in JavaScript?
I came across this bit of JavaScript code, but I have no idea what to make out of it. Why do I get "1" when I run this code? What is this strange little appendix of (1) and why is the function wrapped in parentheses?
(function(x){
delete x;
return x;
})(1);
There are a few things going on here. First is the immediately invoked function expression (IIFE) pattern:
(function() {
// Some code
})();
This provides a way to execute some JavaScript code in its own scope. It's usually used so that any variables created within the function won't affect the global scope. You could use this instead:
function foo() {
// Some code
}
foo();
But this requires giving a name to the function, which is not always necessary. Using a named function also means at some future point the function could be called again which might not be desirable. By using an anonymous function in this manner you ensure it's only executed once.
This syntax is invalid:
function() {
// Some code
}();
Because you have to wrap the function in parentheses in order to make it parse as an expression. More information is here: http://benalman.com/news/2010/11/immediately-invoked-function-expression/
So to recap quickly on the IIFE pattern:
(function() {
// Some code
})();
Allows 'some code' to be executed immediately, as if it was just written inline, but also within its own scope so as not to affect the global namespace (and thus potentially interfere with or be interfered with by, other scripts).
You can pass arguments to your function just as you would a normal function, for example,
(function(x) {
// Some code
})(1);
So we're passing the value '1' as the first argument to the function, which receives it as a locally scoped variable, named x.
Secondly, you have the guts of the function code itself:
delete x;
return x;
The delete operator will remove properties from objects. It doesn't delete variables. So;
var foo = {'bar':4, 'baz':5};
delete foo.bar;
console.log(foo);
Results in this being logged:
{'baz':5}
Whereas,
var foo = 4;
delete foo;
console.log(foo);
will log the value 4, because foo is a variable not a property and so it can't be deleted.
Many people assume that delete can delete variables, because of the way autoglobals work. If you assign to a variable without declaring it first, it will not actually become a variable, but a property on the global object:
bar = 4; // Note the lack of 'var'. Bad practice! Don't ever do this!
delete bar;
console.log(bar); // Error - bar is not defined.
This time the delete works, because you're not deleting a variable, but a property on the global object. In effect, the previous snippet is equivalent to this:
window.bar = 4;
delete window.bar;
console.log(window.bar);
And now you can see how it's analogous to the foo object example and not the foo variable example.
It means you created an anonymous function, and call it with parameter 1.
It is just the same as:
function foo(x) {
delete x;
return x;
}
foo(1);
The reason that you still get 1 returned is that the delete keyword is for removing properties of objects. The rest is as others have commented, anything wrapped in brackets executes as a function, and the second set of brackets are the arguments passed to that block.
Here's the MDN reference for delete, and the MDN reference for closures, which discusses also anonymous functions.
People normally call these "Immediately Invoked Function Expressions" or "Self Executing Functions".
The point of doing this is that variables declared inside that function do not leak to the outside.

Categories