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
}