So I want to call function B in function A, but function B is fully declared after function A. I know that in c++ we'd use function prototypes on B, but what about javascript?
code:
markerArray = function() {
// some code here
this.array = [];
this.clearArray = function() {
for(var i = 0; i<this.getLength(); i++)
// for loop code
}
this.getLength = function() {
return this.array.length;
}
// some code here
}
these reason why I put this.getLength below is mainly because my coding style/structure is more readable this way
Javascript doesn't care about this requirement. It will simply work as long as Function A isn't called until after the file is loaded. Function A will be defined, Function B will be defined, then Function A can be called using Function B inside of it with no problem.
Not a problem. Function declarations are hoisted to the top of the enclosing variable environment, so they do not need to be declared in order.
A();
function A() {
B();
}
function B() {
alert('B was called');
}
If you meant something else, you'll need to explain it in your question.
It depends on how you declare your functions. If you declare a function via the Function constructor or a function expression, order matters.
a(1); //this call won't work
//function expression of an anonymous function assigned to the variable multiply
var a = function(i) {
b(i);
}
// b is defined using Function constructor
var b = new Function("i","alert('B was called with ' + i)");
a(1); //this call will work
Related
For example:
(function foo() {
var a = 3;
console.log(a);
});
var obj = {
a: (function foo() {
var a = 2;
console.log(a);
})
};
obj.a(); // 2
foo(); // ReferenceError: Not Defined
How is that I can access a function expression within obj, but not in the global object?
Edits: for cohesion and clarity
You're confusing a couple of different things here.
Your first statement is a function expression, not a function declaration:
(function foo() {
var a = 3;
console.log(a);
});
This happens to be a named function expression ("foo"), but it does not introduce a variable foo in this scope. If you wanted to introduce foo so that it can be called again, you need either a function declaration...
function foo() {
var a = 3;
console.log(a);
}
foo();
or, you need to assign the function expression to a variable:
var foo = function () {
var a = 3;
console.log(a);
}
foo();
Your next bit of code, the object declaration, effectively does this by assigning the function expression to a variable, obj.a:
var obj = {
a: (function foo() {
var a = 2;
console.log(a);
})
};
The error in your thinking here is due to confusion around foo. In both cases, foo is the name of the function, but it's not actually relevant to invoking the function. You should drop the foo because it's only confusing things.
In essence, your first snippet is equivalent to:
(function () { alert('x'); });
This line of code defines an anonymous function, but does nothing with it. The function exists briefly, is never invoked, and then is lost, because it is not assigned to anything.
Your second snippet is equivalent to:
var x = function () { alert('y') };
This code defines a variable, x, and assigns a function to it. The function can then be invoked with x(), and the function remains available as long as x is in scope.
Your original question is:
How can an object access function expression?
Which doesn't really make sense. The object can't "access the function expression", it just contains a property to which a function has been assigned, while the snippet outside the object did not retain the function in a way that would allow you to invoke it.
Can anyone explain why
function x() {
console.log("Hello!");
}
var a = x;
a();
x();
produces
Hello!
Hello!
but this
var a = function x() {
console.log("Hello!");
}
a();
x();
throws an error when you try to call function x? Is the second x function not considered a hoisted function? I tried this in both nodejs and a browser.
What you have in the second example is what's called a named function expression.
Its name is not added to the containing scope, but is accessible within the scope of the function itself:
var a = function x() {
alert(x);
};
a();
This is useful in writing recursive functions or functions that otherwise reference themselves, as it ensures that the name won't get clobbered due to anything that happens outside the function's scope.
It also allows you to create self-referencing functions in places where you can't use a function declaration, such as in an object literal:
var myFavoriteFunctions = {
factorial: function f(n) {
return n === 1 ? 1 : n * f(n);
},
identity: function (v) { return v; }
};
console.log(myFavoriteFunctions.factorial(10));
Your first example is a function statement, which declares a name in its containing scope.
Your second example is a named function expression, which does not.
For more information, see here.
so a simple example would be
function a() {
alert("something");
}
anything.onclick = a; // this is without parentheses
anything.onclick = a(); // this is with parentheses
What is the difference between the two?
And one thing more: if I define the same function but this time return false, will it work?
function a(){
alert("something");
return false;
}
The difference is that a() calls the function while a is the function.
console.log( a() ); // false
console.log( a ); // function() {...}
To make it clear what technically happens when you use the second part of your example, let's redefine alike this:
a = function() {
return 100;
};
and set the event handler:
anything.onclick = a();
f() not only calls the function f but returns its return value. So when setting a variable or object property to a function call, the return value of the function call will be assigned. So the above statement is effectlively equivalent to:
anything.onclick = 100;
which doesn't make sense and might cause an error. If a function doesn't have a return value, its return value is implicitly undefined.
However, if you had set a variable equal to a without calling it, it would be the same as setting a regular function expression to that variable:
var a = function() { ... },
b = a; // b = function() { ... }
b would perform the same operation as a would.
So in your example go with the first one because it makes sense! The only case in which you would assign the return value of the function call to an event handler is if the function returns another function. For instance:
var x = function(xyz) {
return function() {
console.log(xyz);
};
};
anything.onclick = x("Hello World"); // = function() {
// console.log("Hello World");
// }
Assigns reference:
anything.onclick = a; //assigns a reference
With your function it is:
anything.onclick = function() {
alert("something");
}
Executes method and assigns the returned result
anything.onclick = a(); //calls the method and assigns whatever is returned.
With your function it is:
anything.onclick = false;
The parenthesis at the end of the function is the permission for javascript engine to execute the function. If you don't supply it, it won't be executed at all.
If you do x=a() you are invoking the function but if you do x=a you are passing a pointer to a function
long story short:
Let's say we have
function f(){} or f = function(){}
If you now write
someFunction(f());
it will call f() and whatever f() returns will be passed as argument to someFunction().
If you write
someFunction(f);
on the other hand (when defined like the latter), f will be passed to someFunction() as (a variable holding) the function.
This could be used e.g. if the function is supposed to be used later on but maybe can't be called some other ('normal') way.
( Of course, depending on language, "function" could obviously be a "method" and the language could not even have function-variables or however you call it! )
( off topic: note that this answer says the same as the other answers because that is THE true answer but I did not want to edit the other answers because each may be found differently helpful by different people )
I use only jQuery for writing JavaScript code. One thing that confuses me is these two approaches of writing functions,
First approach
vote = function (action,feedbackId,responseDiv)
{
alert('hi');
return feedbackId;
}
Second approach
function vote(action, feedbackId,responseDiv)
{
alert('hi');
return feedbackId;
}
What is the difference between the two and why should one use the first approach or the second approach?
The first is a function expression assigned to the vote variable, the second is a function declaration.
The main difference is that function statements are evaluated at parse time, they are available before its declaration at runtime.
See also:
Named function expressions demystified (article)
Explain JavaScript’s encapsulated anonymous function syntax
function myFunction() {}
...is called a "function declaration".
var myFunction = function() {};
...is called a "function expression".
They're very similar; however:
The function declaration can be declared after it is referenced, whereas the function expression must be declared before it is referenced:
// OK
myFunction();
function myFunction() {}
// Error
myFunction();
var myFunction = function() {};
Since a function expression is a statement, it should be followed by a semi-colon.
See Function constructor vs. function declaration vs. function expression at the Mozilla Developer Centre for more information.
The function declaration syntax cannot be used within a block statement.
Legal:
function a() {
function b() {
}
}
Illegal:
function a() {
if (c) {
function b() {
}
}
}
You can do this though:
function a() {
var b;
if (c) {
b = function() {
};
}
}
The first one is a function expression,
var calculateSum = function(a, b) { return a + b; }
alert(calculateSum(5, 5)); // Alerts 10
The second one is a plain function declaration.
My attempts at giving global scope to a nested JavaScript function are not working:
//DECLARE FUNCTION B IN GLOBAL SCOPE
function B;
function A() {
//DEFINE FUNCTION B INSIDE NEST
B() {
alert("function B is running");
}
}
//CALL FUNCTION B FROM GLOBAL SCOPE
B();
This is just curiosity -- you are correct that I don't really have any good reason to want to do this.
TIA -- I don't have an SO account to respond to your answers...
function B; will simply generate a syntax error.
You can use a function expression. As functions are first class objects, you can assign a function to a variable:
var B; // declare (global) variable (outer scope)
function A() {
// assign a function to it
B = function() {
alert("function B is running");
};
}
// we have to call A otherwise it won't work anyway
A();
// call B
B();
You could also let A return a function:
function A() {
return function() {
alert("function B is running");
};
}
B = A();
This would make the relation between A and B a bit clearer.
Of course you can always define a global variable by omitting var, but you should use this very carefully. Use as less global variables as possible.
function A() {
B = function() {
alert("function B is running");
};
}
And I bet there is a better way of doing it, depending on what your actual goal is.
More about Functions and function scope.
What about:
function A() {
window.B = function() {
alert("function B is running");
}
}
//CALL FUNCTION B FROM GLOBAL SCOPE
B();
You can do something like this:
function outer() {
function inner() {
// ..
}
window['inner'] = inner;
}
It's a little icky to have a direct reference to "window", so you could do this (from the global context):
(function (global) {
function inner() {
// code code code ...
}
global['inner'] = inner;
})(this);
There appear to be a couple of issues with your code
The first line doesn't appear to be legal Javascript (JSLint agrees). To declare an uninitialized variable use the var B; syntax
The code never calls A to initialize B so calling B() is invoking an uninitialized variable
I'm fairly certain the code to initialize B inside of A is also not legal.
Try the following
var B; // Establish B as a global scope variable
function A() {
B = function() {
alert('B is running');
};
}
A(); // Call the function which will cause B to be initialized
B(); // Run B
You're close, but not completely correct.
You have to define B as a variable and then assign a function to it.
Also run A() before executing B, otherwise B will be undefined. The easiest way of running it is the way that I show in my code example.
These are the smallest amount of changes to your code to make it work as you asked:
var B;
(function A() {
// define function B
B = function() {
alert("function B is running");
}
})();
// call function B globally
B();