I suspect that the Codex information for has_term() is incorrect:
<?php has_term( $term, $taxonomy, $post ) ?>
And for the $taxonomy parameter:
$taxonomy (string)
(optional) Taxonomy name
Default: ”
But if you look at the source for has_term():
$r = is_object_in_term( $post->ID, $taxonomy, $term );
So, $taxonomy is passed to is_object_in_term():
<?php is_object_in_term( $object_id, $taxonomy, $terms = null ) ?>
Which says for the $taxonomy parameter:
$taxonomy (string)
(required) A single taxonomy name.
Default: None
(A look at source for is_object_in_term() confirms that the $taxonomy parameter is required, and will result in returning false if not passed.)
So, it would appear that failing to pass $taxonomy to has_term() will result in has_term() returning false.
It appears that the source inline docs have been updated accordingly:
* @param string|int|array $term Optional. The term name/term_id/slug or array of them to check for.
* @param string $taxonomy Taxonomy name
* @param int|object $post Optional. Post to check instead of the current post.
* @return bool True if the current post has any of the given tags (or any tag, if no tag specified).
The $taxonomy parameter is no longer listed as Optional.