slevin
slevin

Reputation: 3896

execution order of javascript functions

I am back to the basics, in order to better understand JavaScript. I have a testing website. Here is my code

<html>
<head>
test
</head>

<script type="text/javascript">
function saySomething(message)
{
alert(message);
}

saySomething('Hello world!');

function addLoadListener(fn){
window.addEventListener('load', fn, false);
alert("the previous alert came from onload");
}

addLoadListener(saySomething);


</script>


<body>
<div>blah blah blah</div>
</body>
</html>

So, there is this function, saySomething that alerts Hello World!. I add it to addLoadListener so it can be called during page loading. And works fine till this part. But after that, gets called again as the code runs and alerts [object Event] instead of Hello World!. Why? What am I missing?

Thanks

Upvotes: 0

Views: 146

Answers (5)

simich
simich

Reputation: 368

The problem is that once you attach the saySomething function as an event listener to the load event of the window it is later called with different arguments when the event fires. Actually the argument is an event object, that's why you see [object Event] alerted.

While I don't know the real purpose of your code, if you want to alert the "Hello World!" string and you don't need the event arguments that come with the fired event, you can bind the first argument of the saySomething function to "Hello World!":

var boundHandler = saySomething.bind(window, "Hello World!");
addLoadListener(boundHandler);

Edit: Function.prototype.bind creates a new function where this and all of the arguments of the new function can be 'bound' to specific values. It's important to note that bind creates a new function and the original one is preserved. You can create as many bound versions of the original as you want.

If you call boundHandler("something else") or boundHandler(), "Hello World!" will still be alerted instead of the new text. That is why the event handling code later works.

If you create a bound function in this way:

function alertThis() { alert(this); }
var boundFn = alertThis.bind("my new this");

alertThis() // "[object Window]" is alerted
boundFn() // "my new this" is alerted

Here's more info about Function.prototype.bind: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind.

Upvotes: 4

friedi
friedi

Reputation: 4360

This is because you add this function as an event listener. The first argument of an event listener function is an event object. This is why you're getting [object Event].

You can bind your message to the context object. This is one way of solving your problem:

function saySomething(message) {
    alert(message);
}

function saySomethingListener(message) {
    saySomething(this.message);
}

saySomething('Hello world!');

function addLoadListener(fn) {
    window.addEventListener('load', fn.bind({message: 'Hello world!'}), false);
    alert("the previous alert came from onload");
}

addLoadListener(saySomethingListener);

Upvotes: 1

Stalinko
Stalinko

Reputation: 3656

When "load" event happens it calls your function in this way: "saySomething(event)" - first argument is an event object. Not a string.

So you must change something in your code. For example:

function saySomething(message)
{
    var msg = typeof message != 'string' ? 'Hello world!' : message; //setting default message
    alert(msg);
}

Upvotes: 1

Sudharsan S
Sudharsan S

Reputation: 15403

<script type="text/javascript">
  function saySomething(message)
  {
 alert(message);
 }

 saySomething('Hello world!');

function addLoadListener(fn){
  window.addEventListener('load', fn, false);
alert("the previous alert came from onload");
}

 addLoadListener( function() { saySomething('Hello world!') });


 </script>

Upvotes: 1

Coder
Coder

Reputation: 220

May be you are missing your argument

<html>
 <head>
 test
 </head>

 <script type="text/javascript">
  function saySomething(message)
  {
 alert(message);
 }

 saySomething('Hello world!');

function addLoadListener(fn){
  window.addEventListener('load', fn, false);
alert("the previous alert came from onload");
}

 addLoadListener(saySomething('Hello world!'));


 </script>


  <body>
  <div>blah blah blah</div>
  </body>
  </html>

Upvotes: -3

Related Questions