Anonymous function question

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

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

with a named function. I tried replacing it with

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) ?

The “mousemove” function is not a native event for an element. Could you please tell us more details about the error scenario?

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:

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:

element.onmousemove = function(event){......};

For your second code block:


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:


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.


alert(a);//undefined
var a = 10;


var a = 10;
alert(a);//10;

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

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

bar() //I work just fine!!

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!

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


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


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

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


function bar() {
    ...
}
element.onmousemove = bar;

// or

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

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.

P.S. I tried moving the function call to after the function declaration, but it didn’t help.

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:


<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