Around 30 years ago (five years before advent of Javascript), I built a successful company around a distributed network programming framework that used prototype based objects. Objects in object oriented systems usually share some behavior via common methods, and they share some structure for their data members; the methods and structure are described by the object's class. Classes are language constructs with their own complex behaviors.
A class is like a blueprint used by the language compiler and runtime to build (allocate) objects. In languages like Python, Ruby, Smalltalk, or Common Lisp these classes are present in some form at runtime controlling the memory allocation of objects, the initialization of member fields, the dispatching of generic or virtual functions and so forth. Since the classes are present in some shadowy form at runtime, they themselves have behaviors controlled by meta-classes which in some languages can be manipulated at runtime (e.g. monkey-patching).
Prototype based object systems don't use classes to accomplish this sharing of behavior and structure. Such systems have a conceptually simpler set of primitives to accomplish the sharing and classes aren't needed. In prototype based systems one can clone an existing object, even an empty object. After cloning an object one can add fields to the object.
Structural sharing is easy with prototypes. If a program would like to make use of objects representing screen coordinates, first construct a prototype:
Coordinate2D = clone(empty_object)
Coordinate2D.add_field(x).add_field(y)
Like fields, methods can be added to the prototype:
Coordinate2D.add_method(clear)
Coordinate2D.clear = {self.x = 0; self.y = 0}
Next to create an object of type coordinate just clone the prototype:
location = clone(Coordinate2D)
location.x = 10
location.y = 16
Prototype based systems are appealing because of the underlying language semantics and runtime implementation are very simple.
Smalltalk, CLU, Common Lisp's CLOS (The Art of the Meta-Object Protocol), and Self all inspired design decisions that went into the Tivoli Systems distributed programming framework.