SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Member
    Join Date
    Apr 2004
    Location
    Costa Rica
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Anonymous function question

    In the course of updating some code, I need to replace the anonymous function

    Code:
    element.mousemove(function (event) {.......

    with a named function. I tried replacing it with

    Code:
    element.mousemove = moveMouse;                             		
    function moveMouse(event) {.......
    but this causes the code to fail.

    Can anyone please explain to me why the two above code blocks don't do exactly the same thing (execute the code that follows the anonymous function call, or is contained in the moveMouse function) ?

  2. #2
    SitePoint Member
    Join Date
    Sep 2010
    Location
    Shanghai, China
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The "mousemove" function is not a native event for an element. Could you please tell us more details about the error scenario?

  3. #3
    SitePoint Member
    Join Date
    Apr 2004
    Location
    Costa Rica
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No error, nothing shows in the error console, the function just does not fire.
    The code was working before. All I did was replace the upper block of code above with the lower block, and add the required closing parenthesis at the end of the function (no syntax errors). This caused the code to stop working.

  4. #4
    SitePoint Member
    Join Date
    Sep 2010
    Location
    Shanghai, China
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by gavacho View Post
    No error, nothing shows in the error console, the function just does not fire.
    The code was working before. All I did was replace the upper block of code above with the lower block, and add the required closing parenthesis at the end of the function (no syntax errors). This caused the code to stop working.
    I see!
    Firstly, I am so sorry that "mousemove is not a native event" is wrong. I must correct that. mousemove event is one of standard mouse events described by W3C.

    Secondly, for your question, it is an issue about how js engine process js code internally.
    For your first code block:
    Code:
    element.mousemove(function(event){......})
    which is not correct. I don't know why you can run these correctly. If you wanna bind an mousemove event on element, you can write it like this:
    Code:
    element.onmousemove = function(event){......};
    For your second code block:
    Code:
    element.onmousemove = mouseMove;
    function mouseMove(event){.......};
    When the js engine is entering execution context which is the first step of the process of execution code described by ECMAScript 262 3rd, js engine internally creates VO(Variable Object) which belongs to its own context. VO is used to store some variable declarations including following description said by ECMAScript:
    1. formal parameters of function
    2. function declaration(function identifier)
    3. variable declaration

    so, for your second code, VO for global context(implemented as a global object) is like this:
    VO = {
    mouseMove: func-----mouseMove(just a reference, the actual value(function content) will be updated at code execution stage which is the second stage of the process of execution code)
    }

    These is only mouseMove in the VO for no other declarations found at the entering execution context stage.
    Then the js engine entering the stage of code execution. When it finds this statement:
    element.onmousemove = mouseMove;
    js engine will look up the VO for the value of mouseMove(just a reference, the actual value hasn't been update yet). This is why nothing happens when you mouse the mouse on the element
    After that, js engine finds the next statement:
    function mouseMove(event){....}
    the value of mouseMove in VO will updated and points to the actual function content. Which means any statement using mouseMove will get the actual value.

    In conclusion, you can correct your second code block like this to make it work:
    Code:
    function mouseMove(event){.....};
    element.onmousemove = mouseMove;
    Which just change the sequence of the two code lines but it can make the updating of the mouseMove in VO happen before the event binding statement.
    so, mouseMove will get the actual correct value.

    If you are still in puzzle. You can compare these two code blocks.
    1.
    Code:
    alert(a);//undefined
    var a = 10;
    2.
    Code:
    var a = 10;
    alert(a);//10;

  5. #5
    SitePoint Addict
    Join Date
    Nov 2008
    Location
    Thailand
    Posts
    303
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    element.onmousemove = mouseMove;
    function mouseMove(event){.......};
    Maybe I've got the wrong end of the stick(wouldn't be a first), but I think you've got that wrong.

    There's a difference in how hoisting works between a function declaration and a function expression.

    With a function expression i.e. var foo = function(){}, only the variable is hoisted to the top and assigned undefined. As you pointed out.

    In the case of a function declaration function foo(){} the declaration and the function are hoisted to the top.

    Simple test

    Code:
    function bar(){
      foo();
      return;
      function foo(){ alert('I work just fine!!') }
    }
    
    bar() //I work just fine!!

  6. #6
    SitePoint Member
    Join Date
    Sep 2010
    Location
    Shanghai, China
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks RLM2008.
    I check my test page carefully.
    I write it like this:
    element.onmousemove = mouseMove;
    var mouseMove = function.......

    In which, mouseMove is just a simple declaration and the value will be undefined. So, this code won't work!

    But, if I rewrite code like this:
    element.onmousemove = mouseMove;
    function mouseMove(event){....}

    This works well! So, "At the entering execution context stage, function declaration meant store the function identifier and the value was just an reference, the actual value would be updated at the code execution stage" as I said before was wrong.
    function declaration will make the value of function identifier point to the actual function body!

    So, according to this theory, gavacho's code will work as well as RLM2008's demo!
    gavacho, could you please retest your demo to check if this actually doesn't work well!

  7. #7
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,707
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Results can be variable.

    For example, if it's a function declaration, then that will more than likely work, when the event assignment is performed within the same context

    Code:
    element.onmousemove = bar;
    function bar() {
        ...
    }
    However, if it's a function statement, then that's definately not going to work when it's declared after it's assigned

    Code:
    element.onmousemove = bar;
    var bar = function () {
       ...
    };

    The best results and the least problems are always where you declare the objects before you use them.

    Code javascript:
    function bar() {
        ...
    }
    element.onmousemove = bar;
     
    // or
     
    var bar = function () {
       ...
    };
    element.onmousemove = bar;
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  8. #8
    SitePoint Member
    Join Date
    Apr 2004
    Location
    Costa Rica
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks everyone for the input. It is certain that the top block of code works (it was written by a more capable coder than myself). It is also certain that the bottom block of code doesn't work. I have tested both repeatedly.

  9. #9
    SitePoint Member
    Join Date
    Apr 2004
    Location
    Costa Rica
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    P.S. I tried moving the function call to after the function declaration, but it didn't help.

  10. #10
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,707
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by gavacho View Post
    Thanks everyone for the input. It is certain that the top block of code works (it was written by a more capable coder than myself). It is also certain that the bottom block of code doesn't work. I have tested both repeatedly.
    I can confirm that the bottom block of code, when using the correct event of onmousemove, certainly does work, because function declarations are created before the code runs. It's just not a good idea to use a function before it's declaration, as it leads to other sloppy situations too.

    Sample test code:

    Code html4strict:
    <html>
    <body>
    <p id="aparagraph">A paragraph</p>
    <script>
    var element = document.getElementById('aparagraph');
    element.onmousemove = moveMouse;                             		
    function moveMouse(event) {
        alert(event);
    }
    </script>
    </body>
    </html>

    element.onmousemove waits for the event to be triggered, whereas element.mousemove directly triggers the event.

    It's the same as element.onclick and element.click
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •