I think this explanation of the example contains several errors:

The object anOnion will have a __proto__ property equal to Plant.prototype; if we write, then we will lookup foo in the anOnion object first, then in Plant.prototype (the value of anOnion.__proto__), then in Lifeform.prototype (the value of Plant.prototype set by the call to extend()), and finally in Lifeform.__proto__.

I believe it should read: "then in Lifeform.prototype (the value of Plant.prototype.__proto__ set by the call to extend()), and then in Lifeform.prototype.__proto__", which includes three changes:

the value of Plant.prototype -> the value of Plant.prototype.__proto__

Lifeform.__proto__ -> Lifeform.prototype.__proto__

finally -> then

The first change is clear from the example code, which sets prototype.__proto__.

The second change reflects how the prototype chain works -- the next prototype after prototype p is p.__proto__, whereas Lifeform.__proto__ is the __proto__ property of a constructor, which is usually just the built-in function prototype.

The third change reflects that the prototype chain goes on until null is reached; it can't be inferred from the example code whether Lifeform.prototype.__proto__ is null or points to a further prototype.