I have:
var f1 = function(a){
alert(a)
}
var f2 = function(data, method){
method(data) // the problem is here,
// the method f1 is not called. Is there a way to call that method f1?
// the method f1 might not be in this scope, the method f1 can
// be in a class or like this...
}
f2(a, f1)
The question is: Is there a way to call that f1 from f2, from the passed method?
thanks
EDIT: this is some code I write here, but I miss to set the a. anyway the value of is 5.
EDIT: yes! it was just a tiny stupid error in my original code that missed up, i set the value after calling the method. hehe
Try running your Javascript through a debugger. You'll get a message like a is not defined because the call f2(a, f1) is trying to pass a variable named a but you haven't declared one. However, this code will work:
var f1 = function(a){
alert(a);
}
var f2 = function(data, method){
method(data);
}
var a = 'this is a';
f2(a, f1); // results in alert('this is a')
Yes, this should work fine. In your example however, a is undefined when you make the invocation. Make sure you define it; this could be the reason it's not working.
In other words, changing your example to:
f2(42, f1);
Will alert the number 42.
Related
I need to run a javascript function each 10 seconds.
I understand the syntax must work like follow but I am not getting any success:
function funcName() {
alert("test");
}
var func = funcName();
var run = setInterval("func",10000)
But this isn't working. Any help?
A lot of other answers are focusing on a pattern that does work, but their explanations aren't really very thorough as to why your current code doesn't work.
Your code, for reference:
function funcName() {
alert("test");
}
var func = funcName();
var run = setInterval("func",10000)
Let's break this up into chunks. Your function funcName is fine. Note that when you call funcName (in other words, you run it) you will be alerting "test". But notice that funcName() -- the parentheses mean to "call" or "run" the function -- doesn't actually return a value. When a function doesn't have a return value, it defaults to a value known as undefined.
When you call a function, you append its argument list to the end in parentheses. When you don't have any arguments to pass the function, you just add empty parentheses, like funcName(). But when you want to refer to the function itself, and not call it, you don't need the parentheses because the parentheses indicate to run it.
So, when you say:
var func = funcName();
You are actually declaring a variable func that has a value of funcName(). But notice the parentheses. funcName() is actually the return value of funcName. As I said above, since funcName doesn't actually return any value, it defaults to undefined. So, in other words, your variable func actually will have the value undefined.
Then you have this line:
var run = setInterval("func",10000)
The function setInterval takes two arguments. The first is the function to be ran every so often, and the second is the number of milliseconds between each time the function is ran.
However, the first argument really should be a function, not a string. If it is a string, then the JavaScript engine will use eval on that string instead. So, in other words, your setInterval is running the following JavaScript code:
func
// 10 seconds later....
func
// and so on
However, func is just a variable (with the value undefined, but that's sort of irrelevant). So every ten seconds, the JS engine evaluates the variable func and returns undefined. But this doesn't really do anything. I mean, it technically is being evaluated every 10 seconds, but you're not going to see any effects from that.
The solution is to give setInterval a function to run instead of a string. So, in this case:
var run = setInterval(funcName, 10000);
Notice that I didn't give it func. This is because func is not a function in your code; it's the value undefined, because you assigned it funcName(). Like I said above, funcName() will call the function funcName and return the return value of the function. Since funcName doesn't return anything, this defaults to undefined. I know I've said that several times now, but it really is a very important concept: when you see funcName(), you should think "the return value of funcName". When you want to refer to a function itself, like a separate entity, you should leave off the parentheses so you don't call it: funcName.
So, another solution for your code would be:
var func = funcName;
var run = setInterval(func, 10000);
However, that's a bit redundant: why use func instead of funcName?
Or you can stay as true as possible to the original code by modifying two bits:
var func = funcName;
var run = setInterval("func()", 10000);
In this case, the JS engine will evaluate func() every ten seconds. In other words, it will alert "test" every ten seconds. However, as the famous phrase goes, eval is evil, so you should try to avoid it whenever possible.
Another twist on this code is to use an anonymous function. In other words, a function that doesn't have a name -- you just drop it in the code because you don't care what it's called.
setInterval(function () {
alert("test");
}, 10000);
In this case, since I don't care what the function is called, I just leave a generic, unnamed (anonymous) function there.
Change setInterval("func",10000) to either setInterval(funcName, 10000) or setInterval("funcName()",10000). The former is the recommended method.
That's because you should pass a function, not a string:
function funcName() {
alert("test");
}
setInterval(funcName, 10000);
Your code has two problems:
var func = funcName(); calls the function immediately and assigns the return value.
Just "func" is invalid even if you use the bad and deprecated eval-like syntax of setInterval. It would be setInterval("func()", 10000) to call the function eval-like.
Try this:
function funcName() {
alert("test");
}
var run = setInterval(funcName, 10000)
Btw this didn't work
setInterval(function () {
alert("test");
}, 10000);
I had to give a name (whatever you like) to the anonymous function:
setInterval(function alertNotification () {
alert("test");
}, 10000);
let's say I have I have the following in a file called file1.js:
//constructor
function Blah(){
this.string = "hello there agent ";
}
//'method'
Blah.prototype.greeting = function(num){
return this.string + num;
}
Then in a file called file2.js I then have this:
function combine(num,funct){
return funct(num);
}
And then finally, in an html file called file3, I have this:
var bond = new Blah();
document.write(combine(007,bond.greeting));
I am actually getting into the "greeting" method, but for some reason, the return value, instead of being a string, winds up not being NaN. Any idea why? the greeting() method seems to be ran at the proper time. However, despite that, 007 seems to be getting interpreted as NaN anyway. Again, any suggestions as to what could be causing this?
Thanks a bunch in advance
First, depending on how you call the greeting method, the this value will be different. If you call it like bond.greeting(num) then this will be bond. If you call it like funct(num), where funct is bond.greeting, then this will be the global object. You need to bind this permanently when passing the function along, to maintain its value no matter how you call the function.
Second, 007 === 7. If you want to print out 007 literally, then you should use a string:
combine('007', bond.greeting.bind(bond));
Remember, this depends on how the function gets called, it is dynamic, and resolved an runtime, unless you bind it previously, like we did above.
You're experiencing the special characteristics of the this keyword.
Basically, this resolves to whatever you call a function from. In your case, you're calling it from the global scope from through func(), which makes this == window. (Calling it through bond.greeting() makes this == bond.)
To resolve, this either bind the function or force the resolution:
// note that this method requires a shim for IE 8 and older
document.write(combine(007,bond.greeting.bind(bond)));
or
function combine(num, obj, funct){
// since funct is being called from obj, `this` == obj within the function
return obj[funct](num);
}
document.write(combine(007,bond, 'greeting'));
The problem you have is when you pass the function as argument, it is passed by value, and then you loose the reference to the object who has the element string = "hello there agent "; and when the function is executed, it executes "this.string" which doesn't exist inside the function, it returns undefined. It's a scope issue.
The solution to make it work good, is to pass the reference which is the object bond
function combine(num,obj){
return obj.greeting(num);
}
combine("007",bond); // returns "hello there agent 007"
1) NaN is "Not a number" error. Try encapsulating 007 in quotes
2) Do you need file2.js or could you do without it?
var bond = new Blah();
document.write(bond.greeting("007"));
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";
I am wondering Can you assign a variable to alert ? what does it really mean and do ? For example,
var a = alert('test');
I tried it out, and the alert pops up as soon as the page loads where variable a remains 'undefined' when I call it. Aren't we suppose to make it an anonymous function with the alert inside like
var a = function(){ alert('test'); }
If we want to trigger an alert on something? Why does javascript allow you to do that?
var a = alert('test');
Think of this statement like any other variable assignment. In order to perform the assignment, first the right-hand side is evaluated. In this case it's a function call, so the function is called and its return value is obtained. In alert's case, the return value is undefined. It doesn't return anything.
Then the return value is assigned to a, so a ends up with the value undefined.
As a side effect of the statement, an alert message is displayed. That happens as a consequence of calling alert() and getting its return value.
function foo(x) {
return x * 2;
}
var a = foo(3);
This code is structurally similar to the alert call, and would result in a being 6. But then alert() doesn't return a value. It's more like this:
function bar(x) {
return;
}
var a = bar(3);
Now a is undefined.
var a = alert('test');
This says to execute alert('test') and assign the return value from that function to a variable named a.
This would be no different than:
var max = Math.max(1,2,3,4);
where max would end up with the value 4 in it as the return value from executing Math.max(1,2,3,4).
var a = function(){ alert('test'); }
This says to declare an anonymous function and assign that function object to the variable a. Since the function is just declared, it is not executed at this time. You can execute it in the future with a().
You commented:
I am just wondering why javascript allows we to do that if it doesn't really means anything
Well, JavaScript (and any other language, including English) allows you to do a lot of stuff that does not mean anything, as long as the syntax is valid. For example, the snippets bellow also mean nothing:
var a;
a = a; // so what?
function something() { /* nothing */ }
var b = something(); // very similar to your example!
Wouldn't it be less consistent if you could assign from some functions, but not from others? If the language were typed, that would produce an error, but since it's not, what's the problem with it? If they don't return a value, their return is undefined, and nothing breaks if you try to assign that to a variable. So you can make functions that sometimes return something, sometimes not. That can be an advantage if used wisely. It's a feature, not a problem with the language.
If you do:
var a = function(){ alert('test'); }
You can then do:
a();
since you've defined an anonymous function..
alert is a function so you can't assign anything to it, per se.
If you want something to pop up if a variable has a value, you could do something like -
$(document).ready(function() {
if (someVar != undefined) {
alert(someVar);
}
});
A lot of people say that this is asked too much in the comments, which made me hesitant to ask this, but I still have not found a solution in their answers, mostly because (1) they are typically using jQuery and (2) the questions usually contain technicalities I do not understand.
I have a function with a variable inside. The variable is assigned a function. I'm sure this concept is not exclusive to AJAX, but that is the context I am using it in, if it makes a difference.
function iClick(this)
{
var foo = "I would like to pass this.";
ajax.onreadystatechange = function (foo) { alert(foo); }
}
I want to pass a variable into the function. However, since there is no original function declaration, how do I specify parameters? Can I even do that?
Just don't declare that variable as a parameter in your anonymous function, like this:
function iClick(this)
{
var foo = "I would like to pass this.";
ajax.onreadystatechange = function () { alert(foo); }
}
When you call the first parameter foo it's whatever's calling that callback passes in that's foo inside the function. If you want to reference a previously declared variable just do that, make sure not to use a parameter with the same name.
You can create a function like this
var c="hello";
(function(b){
alert(b)
})(c);
result would be "hello"
You can also do this, but maybe it's not necessary:
function iClick(this)
{
var foo = "I would like to pass this.";
ajax.onreadystatechange = (function(thevar) {
return function () { alert(thevar); };
})(foo);
}
As #John Hartsock referred, the answer that everyone should really remember is this
var c="hello";
(function(b){
alert(b)
})(c);
And that's very important for example in a for loop when there is some async function inside it, because otherwise you don't get the correct item.
Tell me, what comes out from here?
for (var i=0; i<5; i++){
setTimeout(function(){
console.log(i);
}, 1000);
}
Exactly: all 5, because when all the timers are triggered after 1 second, variable i is already at the value 5.
But if you use a self-invoked anonymous function (SIAF) like this
for (var i=0; i<5; i++){
(function (j){
setTimeout(function(){
console.log(j);
}, 1000);
})(i);
}
it does work, since every time the function is evoked, it runs another instance of the function and as any function, it has its own local variables. I do not merely define the function, I also run it right away (through the (); at the end), but then internally a new instance of the function will be created with different internal local variables, as I parse to the function a different variable every time I run it.
I belive you wanted something like that
function handleAjaxRequest(params) {
var context = {'b':'inner', 'c': params['c']};
function rendered(html) {
// render
}
function gotPart(part) {
context['a'] = part;
engine.render(context).addCallback(rendered);
}
ajax.getPart(params).addCallback(gotPart);
}