9

I have a button

var startButton = $('#startButton').get(0);

that I attach the vanilla javascript onclick method to the button and call start on click.

startButton.onclick = start;

I want to use a function expression but (due to hoisting?) this doesn't call start

var start = function() {
  console.log('requesting local stream');
  startButton.disabled = true;
  getUserMedia(constraints, gotStreamSuccess, errorCallback);
}

A declared function does

function start() {
  console.log('requesting local stream');
  startButton.disabled = true;
  getUserMedia(constraints, gotStreamSuccess, errorCallback);
}

How can I write

startButton.onclick = start;

so that it works with a function expression?

Thanks

1
  • Hey Will, don't forget to mark an answer. :-) Commented Dec 28, 2014 at 21:46

3 Answers 3

2

I would agree with you that it's a hoisting issue, you'll have to look within your code to hoist it appropriately before setting startButton.onclick = start;.

Here's what MDN has to say about the syntax: Syntax for on click

It specifically mentions that the function can either be declared or expressed. Which, to me, leads again to the hoising, because function declarations are automatically hoisted.

The MDN for onclick uses a function declaration. I changed the example in this JSFiddle to use a function expression, as you would like to use. With proper hoisting, it is calling the correct method when you click the button.

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

1 Comment

Thanks Adam - looks very much like declared is the best way to go on this
2

Judging by the description of your problem, it seems that you declare (and define) start after assigning it to startButton.onclick. In such case, startButton.onclick will indeed be undefined.

What is hoisted is the variable itself - your code knows it has been declared, but doesn't yet know its value, as the assignment takes place exactly where you have it in the code. Think of it this way: when you use the var keyword, you declare a variable, which, however, is not yet defined. If you happen to immediately assign a value to it, the new value is not visible to the code above the assignment.

Consider the following example:

var a = 1;
console.log(a);
var a = 2;
var a = 3;

Which one of the three values would you expect to be logged in the console? 1, 2 or 3?
You can use var for a single identifier as many times as you want (though I would not recommend it); consecutive declarations are simply ignored, only the assignments are taken into account. Because of that, an assignment cannot be hoisted.

Function declarations, however, are finite in some sense, they can be hoisted in their entirety and that is the reason why using a function declaration worked in your case.

To solve the problem, you could indeed use a function declaration, or perform the variable assignment before startButton.onclick = start; (and I think you don't really need a variable in this particular case, a function declaration is perfectly suitable for this task).

Note that you could also do:

startButton.onclick = function() { // I'm a function expression too!
    // do something here
}

Comments

0

The event attachment must occur after the creation of the function expression.

Checkout about this example

<button id="click">Click</button>
<button id="click2">Click2</button>

$(function(){

  var startButton = $("#click").get(0);
  var startButton2 = $("#click2").get(0);

  startButton.onclick = clickFunc; // wont work

  var clickFunc = function() {
    alert('click');
  };

  startButton2.onclick = clickFunc; // work
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.