简体   繁体   中英

Does a Javascript function have to be defined before calling it?

If I run the function below before defining it, I will get this error...

Uncaught ReferenceError: openModal is not defined

run then define

$(document).ready( function() {

    delay(openModal, 2000);

    delay = function (f, t) {
        setTimeout(function() {
            f();
        }, t);
    };

    openModal = function () {
        $('#modal-box').css( {
            left: $(window).width() / 2 - $('#modal-box').width() / 2,
            top: $(window).height() / 2 - $('#modal-box').height() / 2
        } );
        $('#modal-box').show();
        $('#modal-mask').show();
    };  

});

Now if I define the function first and then call it it works...I have a background in PHP so I am used to being able to access functions globally, am I doing something wrong or do all functions have to be defined before they can be used?

$(document).ready( function() {

    delay = function (f, t) {
        setTimeout(function() {
            f();
        }, t);
    };

    openModal = function () {
        $('#modal-box').css( {
            left: $(window).width() / 2 - $('#modal-box').width() / 2,
            top: $(window).height() / 2 - $('#modal-box').height() / 2
        } );
        $('#modal-box').show();
        $('#modal-mask').show();
    };  

    delay(openModal, 2000);

} );

When you assign a function to a variable, you have to assign it before you can use the variable to access the function.

If you declare the function with regular syntax instead of assigning it to a variable, it is defined when code is parsed, so this works:

$(document).ready( function() {

    delay(openModal, 2000);

    function openModal() {
        $('#modal-box').css( {
            left: $(window).width() / 2 - $('#modal-box').width() / 2,
            top: $(window).height() / 2 - $('#modal-box').height() / 2
        } );
        $('#modal-box').show();
        $('#modal-mask').show();
    };  

});

(Note the difference in scope, though. When you create the variable openModal implicitly by just using it, it will be created in the global scope and will be available to all code. When you declare a function inside another function, it will only be available inside that function. However, you can make the variable local to the function too, using var openModal = function() { .)

Move the function definition outside of the document.ready block, and things will work as you expect. In javascript (as in most languages), you must define a function or variable before making a reference to it.

In your first example, you reference openModal in the call to delay() , but javascript has no way of knowing what openModal is yet.

openModal = function () {
    $('#modal-box').css( {
        left: $(window).width() / 2 - $('#modal-box').width() / 2,
        top: $(window).height() / 2 - $('#modal-box').height() / 2
    } );
    $('#modal-box').show();
    $('#modal-mask').show();
};

$(document).ready( function() {
    delay(openModal, 2000);
});

edit:

TJHeuvel points out that function does some trickery to define functions before anything else is executed in the same block: Why can I use a function before it's defined in Javascript?

I would say, YES. A function always must be defined before calling. But some functions can be Invoked(called) before where they have been defined (HOISTING)

Two different types of functions that I want to write about are :

Expression Functions & Deceleration Functions

1- Expression Functions: A function expression can be stored in a variable so they do not need function names.They will also named as an anonymous function (a function without a name). To invoke (called) they are always need using a variable name.These kind of functions won't work if calls before where it has been defined which means Hoisting is not happening here. We always must define the expression function first and then invoke it.

let lastName = function (family) {
 console.log("My last name is " + family);
};        
let x = lastName("Lopez");

This is how you can write in ES6:

lastName = (family) => console.log("My last name is " + family);
x = lastName("Lopez");

2- Deceleration Functions: Functions are declared with the following syntax are not executed immediately. They are "saved for later use", and will be executed later, when they are invoked (called upon).These type of functions work if you call them BEFORE or AFTER where they have been defined. If you call a deceleration function before where it has been defined - Hoisting - works properly.

function Name(name) {
  console.log("My cat's name is " + name);
}
Name("Chloe");

Hoisting example:

Name("Chloe");
function Name(name) {
   console.log("My cat's name is " + name);
}

In short yes you do have to define it before using a function, but you could use the setTimeout function for your delay which takes a string as the code to exectute:

$(document).ready( function() {

    setTimeOut('openModal()', 2000);

    openModal = function () {
        $('#modal-box').css( {
            left: $(window).width() / 2 - $('#modal-box').width() / 2,
            top: $(window).height() / 2 - $('#modal-box').height() / 2
        } );
        $('#modal-box').show();
        $('#modal-mask').show();
    };  

});

this would work as the function is not called until after it is defined.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM