I have a file, index.php with a tag
<a onclick="listenFilter()" ></a>
and a javascript named test.js linked to my index.php with the function name listenFilter()
$(document).ready(function () {
function listenFilter() {
alert('a');
return false;
}
});
It fails, and my browser says
ReferenceError: listenFilter is not defined
But when I change the script to
function listenFilter() {
alert('a');
return false;
}
It works.
What's different between those two situations?
It is not because the function is defined after the document is loaded. It is because of the scope it is defined in. Script tags in JavaScript automatically bind all variables and function defined in the direct scope of the script tag as global variables (properties of the window object in a browser).
It is because the scope of the function inside the $(document).ready call is unreachable in the global scope, only by other functions in that scope. If you changed it to:
$(document).ready(function () {
window.listenFilter = function listenFilter() {
alert('a');
return false;
}
});
It would work, since you are adding it to the global scope.
$(document).ready(function(){ }) is the same as doing (function(){ })() in the context of this question. Is is a question of scope, not of declaration order. The declaration is being wrapped in a closure which shields it from affecting the global scope.
In the first situation
$(document).ready(function () {
function listenFilter() {
alert('a');
return false;
}
});
You are saying define the function after the DOM is loaded. So at the time the bellow anchor is created, the function listenFilter is not defined.
< a onclick="listenFilter()" ></a>
But in second it will be defined when the anchor is loaded because it's defined while parsing js.
remove this $(document).ready(function () {
<script>
function listenFilter() {
alert('a');
return false;
}
</script>
JavaScript Functions
JavaScript Function Syntax
A JavaScript function is defined with the function keyword, followed
by a name, followed by parentheses ().
Function names can contain letters, digits, underscores, and dollar
signs (same rules as variables).
The parentheses may include parameter names separated by commas:
(parameter1, parameter2, ...)
The code to be executed, by the function, is placed inside curly
brackets: {}
Related
hi this is my codes in a js page with this name script.js
(function ($) {
myfunc()
{
//some jquery codes
}
}
and I use this function in a html page like this
<html>
<script src='js/script.js'></script>
<button id='btnSent'>sent</button>
<script>
(function ($) {
$('#btns').click(function () {
myfunc();
})
}(jQuery));
</script>
</html>
but in console i have an myfunc is undifined error
myfunc is not global - it's only visible inside of the upper (function ($) { block, due to ordinary Javascript scoping rules. Try using just one (outer) function instead, that way anything else in the inner block would be able to see the myfunc which is also in the inner block:
(function ($) {
function myfunc(){
//some jquery codes
}
$('#btns').click(function () {
myfunc();
})
}(jQuery));
If you have to keep the functionality separate for some reason, you could have script.js assign to a window variable:
(function ($) {
window.myfunc = function() {
//some jquery codes
}
})(jQuery);
You are using IIFEs in both cases. The scope of myfunc() is inside the IIFE in your script.js and not in the global scope.
Hence you cant access it from the IIFE in your html.
Either don't use an IIFE in your script.js just have,
function myfunc(jQuery)
{
//some jquery codes
}
or have the myfunc() inside your IIFE in script tag.
This will be helpful for you to understand better about IIFEs
I have the javascript code below:
(function($){
function JsBarcode(){
//Some Code Here
}
})(window.jQuery);
(function ($) {
JsBarcode();
//calls a JsBarcode not within a scope
})(jQuery);
When running the code above, it gives the error below:
Uncaught ReferenceError: JsBarcode is not defined
I am trying to call a function, which is not within the scope. How will I be able to call it?
2 options:
- you change the structure so the second module is inside the first: parent scope is always visible.
- you change the first module exporting the function so that you can access it outside. sample below
var firstModuleHandle = (function($){
var JsBarcode = function(){
//Some Code Here
console.log("can access me?");
}
return {JsBarcode: JsBarcode};
})(window.jQuery);
(function ($) {
firstModuleHandle.JsBarcode();
//calls a JsBarcode not within a scope
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
It is because JsBarcode is declared inside a anonymous function, so it is available only inside the limited scope of the anonymous function in which it is declared.
One possible solution is to move the declaration outside of the anonymous function
Another one is to use a global variable to store the reference to the function as given below
//declare it as a gloal variable
var JsBarcode;
(function ($) {
//assign the value of JsBarcode as the function
JsBarcode = function () {
//Some Code Here
}
})(window.jQuery);
(function ($) {
JsBarcode();
//calls a JsBarcode not within a scope
})(jQuery);
If you are not wanting to clutter global namespace can also make it a property of jQuery ... a mini plugin
(function($){
// assign to $ namespace
$.JsBarcode = function (){
//Some Code Here
}
})(window.jQuery);
(function ($) {
// call jQuery.JsBarcode()
$.JsBarcode();
})(jQuery);
I use this below cod and it works as expected:
<script>
function_two();
function function_two() {
alert("The function called 'function_two' has been called.");
}
</script>
But when I apply to this code below, it doesn't work as expected:
<script>
function_two();
</script>
<script>
function function_two() {
alert("The function called 'function_two' has been called.");
}
</script>
Can someone say why?
This is because of function declaration hoisting. function declarations are hoisted to the top of the script. In the first case, what has actually happened is this:
<script>
function function_two() {
alert("The function called 'function_two' has been called.");
}
function_two();
</script>
The function declaration has been hoisted above the function_two() call.
In the second case, function_two() is contained within a different script element, and the function declaration cannot be hoisted above it - the code in this case remains in the same order, and function_two() ultimately doesn't exist when it is called.
Due to the hoisting of javascript, declarations always get shoved to the top of a scope before execution (you can't see that, js does that itself). That's why you can use the function in your first example before you declared it.
In your second example you use seperate script elements for function declaration and usage. That is not possible, since the first script element get's compiled and executed before the browser starts to compile the second one.
I have a massive javascript file with many function expressions. All of a sudden console gives me the following errors:
In IE
The value of the property 'myFunc' is null or undefined, not a Function object
In Firefox
TypeError: myFunc is not a function
This is how I call the function:
myFunc();
This is the function:
myFunc = function() {
//do stuff
}
This is happening on ALL function expressions. If I change one to a function declaration it works, but then will fail on some other function expression call inside of it. What the heck?
Possibility 1
If you are calling the function expression before it is defined, you will get this error. If you however turn it into a function declaration, the function declaration would get hoisted to the top of the scope, and could be called before or after the actual declaration occurs. So:
functionFoo();
var functionFoo = function() {
};
Will give this error, because you are trying to call the function before it is defined. But:
functionFoo();
function functionFoo() {
}
Will work, because actual function declarations are hoisted to the top of the scope, and can be used anywhere.
Possibility 2
If you are calling the function expression from a different scope that is outside where the function expression is defined, you will get this error. function expressions, like other variables, can only be used within the scope they are defined. So:
$( document ).ready( function() {
var functionFoo = function() {
};
} );
functionFoo();
Will give you an error, because the defining of the function happens in a different scope than the call. But:
$( document ).ready( function() {
var functionFoo = function() {
};
functionFoo();
} );
Will work just fine, because both the defining and the call happen in the same scope.
myfunc() runs successfully when called from within the same js file. but it is undefined (Firebug) when called from an HTML page:
JS file:
$(function() {
myfunc() {
alert('inside myfunc');
}
alert('outside myfunc');
myfunc(); //this successfully runs myfunc()
});
HTML:
<script>
$(function() {
myfunc(); //this doesn't run myfunc(). It's undefined
});
</script>
But when I change myfunc() declaration to:
myfunc = function () { ... }
It's no longer undefined, and runs successfully.
Sorry for this very noob question, but what just happened? Why did it work when I changed the way I declared the function?
It's a matter of scope.
In
$(function() {
myfunc() {
alert('inside myfunc');
}
alert('outside myfunc');
myfunc(); //this successfully runs myfunc()
});
it is only available inside the anonymous function (function() { }), so it would also be unavailable if you were to call it outside of the anonymous function but inside the same js file.
While if you declare it using
myfunc = function () { ... }
myfunc is a global variable and the function is available everywhere.
In the first snippet, myfunc only exists with in the scope of the anonymous function you've defined. In the second snippet, myfunc is not within any visible scope. Finally, in the third snippet when you define myfunc at the top level, it's available at the global scope so any other part of your javascript will be able to call it successfully.
If you find yourself still having trouble understanding variable scope in Javascript, you might want to try reading through some of the results for "javascript scope" on Google for a more thorough explanation.