0

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

4
  • Try the fiddle ,everything is ok jsfiddle.net/X3vLP/1 Commented Mar 31, 2014 at 10:46
  • @PratikJoshi Thanks Patrick, but I dot see another Hello World! after the page load. Also it would be nice if you provide an explanation of why this is happening. Thanks Commented Mar 31, 2014 at 10:48
  • @PratikJoshi You must change the loading mechanism of jsFiddle from onLoad to No wrap - in <head> Commented Mar 31, 2014 at 10:50
  • As you can see you add your function to event listener without any arguments so why do you expect "Hello World"? Browsers call your function and pass event object it is correct behaviour. Commented Mar 31, 2014 at 10:55

5 Answers 5

4

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.

Sign up to request clarification or add additional context in comments.

5 Comments

The purpose of my code is just testing and better understanding the JavaScript behavior. Can you please clarify what tha line exactly does? saySomething.bind(window, "Hello World!"); . Thanks
Sure, I edited my answer to include more info. I hope it helps.
Sorry to bother again, I am not sure I understand the use of window as this value. I red the link you provided and still dont really get what is going on. Thanks agian.
@slevin It's unfortunate that my attempt to help you actually confused you. Let me try to rectify that. In the body of the saySomething function, as you have defined it, this is the window object. bind() creates a new function and its first argument defines the this in the new function. I bound it to the window object to preserve the this of the original in a way. You can use saySomething.bind(null) without issues (this will be null) since you are not using this in the saySomething function.
aha, yes, makes sense now, using null or undefined. Thanks
1
<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>

Comments

1

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);
}

Comments

1

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

Comments

-3

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>

2 Comments

That's not solving the problem. The function saySomething now gets fired immediately and not at the load event.
@Coder Aha! So its the other way around. The function during the onload did not work. Makes sense. Thanks. Way to understand the basics. What is wrong with me?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.