I have following code, I am expecting alert('baz') but it is not working
var foo = function () {
function foo() {
alert('foo');
}
foo.baz = function () {
alert('baz');
}
}
foo().baz();
However If I return foo at the end it works
var foo = function () {
function foo() {
alert('foo');
}
foo.baz = function () {
alert('baz');
}
return foo;
}
foo().baz(); // output:baz
why first one not working and why second is working and what is purpose inner foo??
Because chaining method needs to be returned something. So, in your code you are correctly returning the foo and then it's getting called.
The first one is not working, because the "foo" method is not a void, so it expects a return value. Without a return value, the call to the method will fail. I advice you to trace both of the calls in developer tools, breakpoint each and trace step by step the chain of events.
As for your second question, The purpose is simple, to give foo additional functionality. Usually you won't use nested foo, it's a bad practice, but a prototype. As with an account method. It contains first name, last name and account number, then a prototype of the method is created in order to create withdraw and deposit methods for the specific account.
It's almost identical to working with polymorphic objects in C# or JAVA. instead using override, you use prototype, or in the case of the code above, nested "foo".
In your code you are assigning the function to a variable and not normally. The variable name can be used by the code inside the function to refer the function itself, but the code outside the function can not see it at all.
When you call the function like foo().baz();
it will first call the foo() function and will need a return value (in this case a function referer variable). Then according to the referer variable name it will call the baz() inside the foo(). So to call the function baz() inside foo(), you need to access function first.
Related
For example:
function foo (parameter1, parameter2) {
// does something
}
if (foo) {
foo(parameter1, parameter2);
}
Calling a function without parentheses was talked about in a different question (In JavaScript, does it make a difference if I call a function with parentheses?), but I still don't understand what the above code does.
I'm asking because I'm trying to understand what if (drag) {..} does in this code: https://andreasrohner.at/posts/Web%20Development/JavaScript/Simple-orbital-camera-controls-for-THREE-js/
Your code defines a global function foo with two parameters.
After that there's an if statement to check if foo is truthy(foo is your function and therefore truthy). So it calls the function foo. But be careful, if foo was not defined your code will throw a ReferenceError.
A much better way to check if a function exists is:
if (typeof foo === "function") {
// safe to use the function foo
}
This code simply check if ~~a function~~ something named foo exists ~~, and therefore safe to call~~.
On the other hand, if you do if (foo()), the code inside that if block will only execute if foo() return something equate to true.
By itself, it's not clear how this code is supposed to be helpful. Maybe with more context it would be clear.
Consider these options:
1. The function foo was never defined:
If foo is not declared then:
if(foo) {}
is a reference error. It crashes.
2. Foo is defined, but it isn't a function
foo can be anything, so if you have foo that looks like this:
let foo = true
if(foo) {
foo()
}
It's an error because you're trying to call something that's not a function.
So what exactly is this piece of code trying to test for? It won't call the function if the name foo is declared and equals some falsy value like 0 or undefined, but in other cases it will crash. It looks like it is trying to protect you from errors, but it doesn't really unless there's some other context where the name is declared but may be undefined.
A common context where foo would be guaranteed to be declared is inside a function where foo is an argument. The code would make more sense in an example like:
someFunction(foo){
if(foo) {
foo()
}
}
Here you can expect foo to exist, but you still need to trust that the caller passed a function. This would guard against a situation where the called does not pass in an argument. (i.e. calling someFunction())
I am reading an article on SitePoint (https://www.sitepoint.com/javascript-closures-demystified/) and there is an example of a first class function:
var foo = function() {
console.log("Hello World!");
};
var bar = function(arg) {
return arg;
};
bar(foo)();
The syntax of the last line looks puzzling to me, and I would have written it as:
bar(foo());
Does anyone know if either syntax is ok, or if there is a good reason for writing it the way the article wrote it? If so, please explain what that reason is.
Thanks,
William
Does anyone know if either syntax is ok,
There are completely different.
bar(foo)() calls bar, passing it foo as an argument, gets the return value of bar and then calls that return value as a function.
bar(foo()) calls foo, gets the return value of foo, then calls bar, passing it the return value of foo as an argument.
there is a good reason for writing it the way the article wrote it
It's a completely contrived example. There's no practical reason to involve bar in this at all. It is just showing that you can pass a function about like any other value (which your version doesn't do).
The term "first class functions" can typically be thought of as the ability to pass functions around the same way you would variables.
The last example is taking foo, which is a function, and passing it into bar(), another function. bar() returns yet another function and that is being called immediately after, hence the extra () at the end. So the way the example was written was not just a stylistic approach; it is showing how functions can be passed around, even into other functions.
bar(foo)();
Calls the function bar, using foo (a function, not the return value of the function) as the argument. Since bar returns the argument, bar ends up returning a function. Adding () at the end causes the returned function to be executed.
bar(foo());
Calls the function bar, using the return value of foo() as the argument
The reason why the code example shows a function being passed as an argument to another function, and being returned from the function is to showcase that functions are objects and can be passed around like one.
The two are fundamentally different and would achieve different things. Let's look at both.
bar(foo)();
This passes a reference to the function bar as the only argument to the function bar, which promptly returns the passed function as the return value, which is then executed via the final ().
Essentially, it's a laborious way of executing foo.
bar(foo());
This first executes foo and passes the return value - which is nothing - as the only argument to bar. Nothing further happens.
The result will be the same, but what the two syntax do are different. When writing bar(foo)();, bar returns a function and then you call this function. It means:
arg in the body of the bar method hold a reference to foo;
bar is executed before foo;
bar returns a function.
Writing bar(foo()), you first call foo and then pass its result to bar. It means:
arg in the body of the bar method holds a reference to the string "Hello World"
foo is called first
bar returns a string
When you write foo, you are referencing the function foo, not the value that this function returns. The function is not executed.
When you write foo(), you are executing the function and returning it's value.
So, when you say bar(foo)(), you are passing a function foo as an argument to bar. Since bar returns any argument it receives, this time it returns the function foo, and then it is being executed.
To simplify, this is what is happening:
var foo = function() {
console.log("Hello World!");
};
var bar = function(arg) {
return arg;
};
var returnFromBar = bar(foo);
returnFromBar();
The following successfully prints 'foo'.
var obj = {
name: 'foo',
printName: function printName() {
console.log(this.name);
}
};
var printButton= document.getElementById('printIt');
printButton.addEventListener('click', function(){
obj.printName();
});
The following doesn't, however:
printButton.addEventListener('click', obj.printName() );
I know the solution... simply use bind so that we're referencing the obj object. i.e:
printButton.addEventListener('click', obj.printName.bind(obj) );
Why then don't we need to use bind in the first example. I don't know why wrapping obj.printName() function call in the anonymous function results in the console.log correctly referencing and printing this properly, but when called directly after click, you needs to use bind
Alright, I commented with some good information on this question so I might as well answer!
Functions are first class
Okay, let's starts with some fundamentals of javascript that is very dissimilar to some other programming languages: in javascript functions are first class citizens--which is just a fancy way of saying that you can save functions into variables and you can pass functions into other functions.
const myFunction = function () { return 'whoa a function'; }
array.map(function () { return x + 1; });
And because of this wonderful feature, there is a big difference between the expressions:
Expression 1
obj.printName
and
Expression 2
obj.printName();
In expression 1: the function isn't being invoked so the value of the expression is of type function
In expression 2: the function is being invoked so the value of the expression is what the function returns. In your case, that's undefined
addEventListener
The method addEventListener takes in two arguments:
a string of the type of event
a function that will be run when the event fires.
Alight, so what does that mean?
When you call
// doesn't work
printButton.addEventListener('click', obj.printName() );
you're not passing a value of type function to the addEventListener method, you're actually passing undefined.
// works
printButton.addEventListener('click', obj.printName.bind(obj) );
then works (for one reason) because the second argument is actually of type function.
What does bind do? Why does it return a function?
Now we need to discuss what bind actually does. It related to the pointer* this.
*by pointer, I mean a reference identifier to some object
bind is a method that exists on every function object that simply binds the this pointer of a desired object to the function
This is best shown by an example:
Say you have a class Fruit that has a method printName. Now that we know that you can save a method into a variable, let's try that. In the example below we're assigning two things:
boundMethod which used bind
unboundMethod that didn't use bind
class Fruit {
constructor() {
this.name = 'apple';
}
printName() {
console.log(this.name);
}
}
const myFruit = new Fruit();
// take the method `printName`
const boundMethod = myFruit.printName.bind(myFruit);
const unboundMethod = myFruit.printName;
boundMethod(); // works
unboundMethod(); // doesn't work
So what happens when you don't call bind? Why doesn't that work?
If you don't call bind in this case, the value of the function that gets stored into the identifier unboundMethod can be thought to be:
// doens't work
const unboundMethod = function() {
console.log(this.name);
}
where the contents of the function is the same contents of the method printName from the Fruit class. Do you see why this is an issue?
Because the this pointer is still there but the object it was intended to refer to is no longer in scope. When you try to invoke the unboundMethod, you'll get an error because it couldn't find name in this.
So what happens when you do use bind?
Loosely bind can be thought of as replacing the this value of function with the object you're passing into bind.
So if I assign: myFruit.printName.bind(myFruit) to boundMethod then you can think of the assignment like this:
// works
const boundMethod = function() {
console.log(myFruit.name);
}
where this is replaced with myFruit
The bottom-line/TL;DR
when to use bind in an Event Handler
You need to use Function.prototype.bind when you want to replace the thises inside the function with another object/pointer. If your function doesn't ever use this, then you don't need to use bind.
Why then don't we need to use bind in the first example?
If you don't need to "take the method" (i.e. taking the value of type of function), then you don't need to use bind either Another way to word that is: if you invoke the method directly from the object, you don't need bind that same object.
In the wrapper function, you're directly invoking the method of the object (as in expression 2). Because you're invoking the method without "taking the method" (we "took" the methods into variables in the Fruit example), you don't need to use bind.
printButton.addEventListener('click', function(){
// directly invoke the function
// no method "taking" here
obj.printName();
});
Hope this helps :D
Note: You need to call printButton.addEventListener('click', obj.printName() ); without parenthesis in obj.printName() since you want to pass the function.
The answer lies in the way this is bound in Javascript. In JS, the way a function is called decides how this is bound. So when you provide the callback function like below:
printButton.addEventListener('click', function(){
obj.printName();
});
Notice, printName is being called via dot notation. This is called implicit binding rule when this is bound to an object before dot, in this case obj. Clearly in this case, you get the expected output.
However, when you call it like this:
printButton.addEventListener('click', obj.printName );
Notice that, all you are passing is the address of the function that is inside obj. So in this case info about obj is lost. In other words, the code that calls back the function doesn't have the info about obj that could have been used to set this. All it has is the address of the function to call.
Hope this helps!
EDIT:
Look at this crude implementation I call bind2 that mimics native bind. This is just to illustrate how native bind function returns a new function.
Function.prototype.bind2 = function (context) {
var callBackFunction = this;//Store the function to call later
return function () { //return a new function
callBackFunction.call(context);//Later when called, apply
//context, this is `obj` passed
//in bind2()
}
};
function hello() {
alert(this.name);
}
obj = {
name:'ABC'
};
var f = hello.bind2(obj);
f();
Notice: How function f() is hard bound here. f() has hard bound this with obj. You cannot change this to other than obj now. This is another thing with bind that probably will help you knowing.
This question already has answers here:
What is the difference between a function call and function reference?
(6 answers)
Closed last year.
I was following a tutorial on AJAX, and the person making the video did something strange. At least I hadn't seen it before. They set an object property equal to a function name, but without the familiar (). He later went on to define the function. Code is provided below for context. Anyway, what does it mean to set something equal to a function without the parameters? That line of code is indeed running the function that is named that as you can see below.
xmlHTTP.onreadystatechange = handleServerResponse;
There's a function called "handleServerResponse()", that this line actually runs. I can post it, but I think it's irrelevant. It's just a normal function function handleServerResponse(). Any explanation would be greatly appreciated!
Thanks!
~Carpetfizz
EDIT: Adding () to the end of that line, creates errors, as well as changing it.
What they're doing there is referring to the function without calling it.
var x = foo; // Assign the function foo to x
var y = foo(); // Call foo and assign its *return value* to y
In JavaScript, functions are objects. Proper objects. And so you can pass references to them around.
In that specific case, what they're doing is setting up handleServerResponse as the callback that the XHR object uses when the ready state changes. The XHR object will call that function during the course of doing the ajax request.
Some more examples:
// Declare a function
function foo() {
console.log("Hi there");
}
// Call it
foo(); // Shows "Hi there" in the console
// Assign that function to a varible
var x = foo;
// Call it again
x(); // Shows "Hi there" in the console
// Declare another function
function bar(arg) {
arg();
}
// Pass `foo` into `bar` as an argument
bar(foo); // Shows "Hi there" in the console, because `bar`
// calls `arg`, which is `foo`
It follows on naturally from the fact that functions are objects, but it's worth calling out specifically that there's no magic link between x and foo in the above; they're both just variables that point to the same function. Other than the fact they point to the same function, they're not linked in any way, and changing one (to point at another function, for instance) has no effect on the other. Example:
var f = function() {
console.log("a");
};
f(); // "a"
var x = f;
x(); // "a"
f = function() {
console.log("b");
};
f(); // "b"
x(); // "a" (changing `f` had no effect on `x`)
When the state of the request changes (for example when the browser received the complete answer), the browser will call a function stored in the onreadystatechange property of the xmlHttpRequest. This call will be something like
xmlHTTP.onreadystatechange();
which will be just equivalent to
handleServerResponse();
To decide what function will be called, you assign this function (not the returned value of this function) to this property using the line you show.
This is possible because JavaScript is a language where functions are said first class : they may be property values just like objects, strings, etc.
It means you are assigning the variable a reference to that function. The reference then can be used to call the function instead. Something like this...
function foo(){
alert("I am inside foo");
}
var bar = foo; // bar now points to foo
// Call foo
foo();// alerts "I am inside foo";
// Call bar which is pointing to foo
bar();// alerts "I am inside foo";
Why is it that when I use the dojo.hitch function and try to reference the "this" operator inside it, that it gives me reference to the wrong object?
console.debug(dijit.byId("widgetName")); //works as expected and prints out the window object
dojo.hitch(dijit.byId("widgetName"), tester())(); //this should be executing the tester function in the scope of the widget object
function tester() {
console.debug(this); //prints out the Javascript Window object instead of the widget object!!!!
}
Thanks
Based on what you have just shown, I can now safely provide an answer explaining what is wrong.
When you do a dojo.hitch() you should not call the function inside of it, but instead call the result of the function. That is, you need to provide dojo.hitch with a reference to the function to hitch, not the result of invoking that function.
In your example, you are calling tester() (which invokes the function tester) inside of the dojo.hitch(), which calls the tester once. Even though you have dojo.hitch()(); because tester() does not return a function handler (but the result of tester, in this case undefined), the hitch()(); does nothing. That might have been confusing so I will show you with an example.
Don't do this:
dojo.hitch( context, handler() )();
Instead do this:
dojo.hitch( context, handler )();
So to make what you have very readable you would do this:
widget = dijit.byId("widgetName");
tester = function() {
console.log(this);
}
handle = dojo.hitch(widget, tester);
handle();
Your mistake was trying to call the function from within the dojo.hitch(). This mistake also was not present in your original question.