Because the prototype behind the rabbit instance is assigned (from Rabbit.prototype) when it's created via new Rabbit, and in the first example you replace Rabbit.prototype with an entirely new object, which has no effect on the rabbit instance. In the second example, you just modify the existing object, which both Rabbit.prototype and the prototype behind rabbit are pointing to, so since they're pointing to the same object, you see the change regardless of which reference you follow.
Let's walk through var rabbit = new Rabbit(); (leaving out some irrelevant details):
A new, blank object gets created.
Its underlying prototype, usually called [[Proto]], is set to Rabbit.prototype. (I say "usually called" because that's what the specification calls it. You can't access it by that name directly. You can find out what it is for a given object, though, in an ES5-enabled environment via Object.getPrototypeOf. Some JavaScript engines also make it available via a non-standard property actually called [in code] __proto__.)
That new object is returned and assigned to rabbit.
Now, we have two objects pointing to the prototype object: Rabbit.prototype, and rabbit.[[Proto]].
In your first example, you change Rabbit.prototype to point to an entirely new, different, object. So now Rabbit.prototype and rabbit.[[Proto]] no longer point to the same object.
In your second example, you just change the value of that shared object's eats property, so naturally that change is visible regardless of which reference to the object you follow.
It's basically the same as this:
var a = {eats: true};
var b = a;
a = {eats: false};
console.log(a.eats); // false
console.log(b.eats); // true
and
var a = {eats: true};
var b = a;
a.eats = false;
console.log(a.eats); // false
console.log(b.eats); // false