It's more than just the javascript, because even printing value from within my widget prints None, and that's before the form is rendered on the page.
1. Before creating the FORM object you can do
db.table.my_field.default = "my_default"
In this case, the value passed to a widget is "my_default"
2. After creating the FORM but before it form.accepts, you can do
form.vars.my_field = "my_default"
In this case, "my_default" doesn't get passed into the widget as value.
In the 2nd way, I don't fully understand what's going on behind the scenes. Somehow the act of calling form.accepts populates the default into the form, but without calling the widget again. I'm guessing that it looks at the FORM object, finds the element with the id matching my_field, and inserts "my_field" as the value in that element.
Anyway, I guess the take-home message is that if I want my widget to apply custom styling based on a default set on the fly, I should use method 1 above, i.e. db.table.my_field.default = "my_default"