You could still do the following in Java:
Class<? extends FooInterface> c = FooBar.class;
FooInterface newInstance = c.newInstance()
But people usually choose not to, because it still leaves the construction details up to the caller (and forces the class to have a no-arg constructor). The point of a factory is to create a fully "configured" object, e.g. maybe the factory has a set of specific constructor arguments it uses for all the objects it creates, that the caller then doesn't have to know about, etc.
It's true however that people would simply use higher order functions for this in JavaScript, e.g.
function createButtonFactory(color, background) {
return function(text) {
return { type: 'button', color, background, text }
}
}
const buttonMaker = createButtonFactory('grey', 'blue')
and then you can pass `buttonMaker` to somewhere that wants to create buttons by just specifying the text (i.e. some function that will be calling `buttonMaker('hello')`)
This has nothing to do with the language being "dynamic" though, it's about having this specific feature. You could do the same thing in C++ now that it has lambdas.
The contract of the thing that uses the factory is "I need to be able to create buttons by just specifying their text", i.e.
type ButtonMaker = (text: string) => Button
function loadGui(buttonMaker: ButtonMaker)
so the factory has to take care of all the other details (if any) to make that possible.