The Closure Library makes use of the pseudoclassical inheritance pattern, which is particularly compelling when used with the Closure Compiler. Those of you who have read JavaScript: The Good Parts by Douglas Crockford may use the functional pattern for inheritance that he espouses.

Crockford appears to object to the pseudoclassical pattern because: "There is no privacy; all properties are public. There is no access to super methods...Even worse, there is a serious hazard with the use of constructor functions. If you forget to use the new prefix when calling a constructor function, then this will not be bound to a new object...There is no compile warning, and there is no runtime warning."

This article discusses the advantages of the pseudoclassical pattern over the functional pattern. I argue that the pattern used by the Closure Library paired with the Closure Compiler removes existing hazards while I also examine the hazards introduced by the functional pattern (as defined in The Good Parts). First let me demonstrate what I mean by the functional pattern.

Example of the functional pattern

The following is an example in the style of the functional pattern for inheritance as explained in Douglas Crockford's JavaScript: The Good Parts. It contains the definition for a phone type as well as a subtype smartPhone.
var phone = function(spec) {
  var that = {};

  that.getPhoneNumber = function() {
    return spec.phoneNumber;
  };

  that.getDescription = function() {
    return "This is a phone that can make calls.";
  };

  return that;
};

var smartPhone = function(spec) {
  var that = phone(spec);
  spec.signature = spec.signature || "sent from " + that.getPhoneNumber();

  that.sendEmail = function(emailAddress, message) {
    // Assume sendMessage() is globally available.
    sendMessage(emailAddress, message + "\n" + spec.signature);
  };

  var super_getDescription = that.superior("getDescription");
  that.getDescription = function() {
    return super_getDescription() + " It can also send email messages.";
  };

  return that;
};
Instances of each of these types could be created and used as follows:
var myPhone = phone({"phoneNumber": "8675309"});
var mySmartPhone = smartPhone({"phoneNumber": "5555555", "signature": "Adios"});
mySmartPhone.sendEmail("noone@example.com", "I can send email from my phone!"); 

Example of the pseudoclassical pattern

Here is the same logic as the previous example, only written using Closure's style and coding conventions.
goog.provide('Phone');
goog.provide('SmartPhone');

/**
 * @param {string} phoneNumber
 * @constructor
 */
Phone = function(phoneNumber) {

  /**
   * @type {string}
   * @private
   */
  this.phoneNumber_ = phoneNumber;
};

/** @return {string} */
Phone.prototype.getPhoneNumber = function() {
  return this.phoneNumber_;
};

/** @return {string} */
Phone.prototype.getDescription = function() {
  return 'This is a phone that can make calls.';
};


/**
 * @param {string} phoneNumber
 * @param {string=} signature
 * @constructor
 * @extends {Phone}
 */
SmartPhone = function(phoneNumber, signature) {
  Phone.call(this, phoneNumber);

  /**
   * @type {string}
   * @private
   */
  this.signature_ = signature || 'sent from ' + this.getPhoneNumber();
};
goog.inherits(SmartPhone, Phone);

/**
 * @param {string} emailAddress
 * @param {string} message
 */
SmartPhone.prototype.sendEmail = function(emailAddress, message) {
  // Assume sendMessage() is globally available.
  sendMessage(emailAddress, message + '\n' + this.signature_);
};

/** @override */
SmartPhone.prototype.getDescription = function() {
  return SmartPhone.superClass_.getDescription.call(this) +
      ' It can also send email messages.';
};
Similarly, here is an example of how these types could be used:
goog.require('Phone');
goog.require('SmartPhone');

var phone = new Phone('8675309');
var smartPhone = new SmartPhone('5555555', 'Adios'};
smartPhone.sendEmail('noone@example.com', 'I can send email from my phone!'); 

Drawbacks to the functional pattern

Instances of types take up more memory
Every time phone() is called, two new functions are created (one per method of the type). Each time, the functions are basically the same, but they are bound to different values.

These functions are not cheap because each is a closure that maintains a reference for every named variable in the enclosing function in which the closure was defined. This may inadvertently prevent objects from being garbage collected, causing a memory leak. The Closure Library defines goog.bind() and goog.partial() in base.js to make it easier to create closures that only maintain the references they need, making it possible for other references to be removed when the enclosing function exits.

This is not a concern when Phone() is called because of how it takes advantage of prototype-based inheritance. Each method is defined once on Phone.prototype and is therefore available to every instance of Phone. This limits the number of function objects that are created and does not run the risk of leaking memory.

Methods cannot be inlined
When possible, the Compiler will inline methods, such as simple getters. This can reduce code size as well as improve runtime performance. Because the methods in the functional pattern are often bound to variables that cannot be referenced externally, there is no way for the Compiler to rewrite method calls in such a way that eliminates the method dispatch. By comparison, the following code snippet:
// phone1 and phone2 are of type Phone
var caller = phone1.getPhoneNumber();
var receiver = phone2.getPhoneNumber();
operator.createConnection(caller, receiver);
could be rewritten to the following by the Compiler:
operator.createConnection(caller.phoneNumber_, receiver.phoneNumber_);
Superclass methods cannot be renamed (or will be renamed incorrectly)
When the Closure Compiler is cranked up to 11, one of the heuristics it uses for renaming is that any property that is not accessed via a quoted string is allowed to be renamed, and the Compiler will do its best to rename it. All quoted strings will be left alone. It is not required to use the Compiler with this aggressive setting, but the potential reduction in code size is too big to ignore.

From the phone example, getDescription is used both as a property defined on that and as a string literal passed to that.superior(). If aggressive renaming were turned on in the Compiler, getDescription would have to be used as a quoted string throughout the codebase so that it did not get renamed. (It could also be declared as an extern, which is what prevents built-in method names, such as toString() from being renamed, but because there is no function to associated the method with, it would have to be declared as an extern on Object.prototype.) Remembering to refer to it via a string literal throughout the codebase is a bear and precludes the benefits of aggressive renaming. (To be fair, some of the constructs in the candidate spec for EcmaScript 5, such as Object.defineProperty(), have similar issues. The solution will likely be to add logic to the Compiler to treat Object.defineProperty() in a special way. The same could be done for superior() if one were so motivated.)

Types cannot be tested using instanceof
Because there is no function to use as the constructor, there is no appropriate argument to use with the right side of the instanceof operator to test whether an object is a phone or a smartPhone. Because it is common for a function to accept multiple types in JavaScript, it is important to have some way to discern the type of the argument that was passed in.

An alternative would be to test for properties that the desired type in question may have, such as:

if (arg.sendEmail) {
  // implies arg is a mobilePhone, do mobilePhone things
}
There are two problems with this solution. The first is that checking for the sendEmail property is only a heuristic -- it does not guarantee that arg is a mobilePhone. Perhaps there is also a type called desktopComputer that also has a sendEmail method that would also satisfy the above test. The second problem is that this code is not self-documenting. If the conditional checked if (arg instanceof MobilePhone), it would be much clearer what was being tested.
Encourages adding properties to Function.prototype and Object.prototype
In Chapter 4 of The Good Parts, Crockford introduces Function.prototype.method and uses it in Chapter 5 via Object.method to add a property named superior to Object.prototype to aid in creating superclass methods. Adding properties to fundamental prototypes makes it harder for your code to play nicely with other JavaScript libraries on the page if both libraries modify prototypes in conflicting ways.

The Google Maps team learned this the hard way when they decided to add convenience methods to Array.prototype, such as insertAt (incidentally, this is exactly what Crockford does in Chapter 6). It turned out that many web developers were using for (var i in array) to iterate over the elements of an array (as opposed to using for (var i = 0; i < array.length; i++) as they should have been). The for (var i in array) syntax includes properties added to Array.prototype as values of i, so bringing in the Google Maps library would break the code on those web pages. Rather than trying to change web developers' habits, the Maps team changed their library. It is for reasons such as these that array.js in Closure is a collection of array utility functions that take an array as their first argument rather than a collection of modifications to Array.prototype.

For those of you who do not own Crockford's book, here is the code in question. Try running the following and see what happens:

// From Chapter 4.
Function.prototype.method = function(name, func) {
  this.prototype[name] = func;
  return this;
};

// From Chapter 5.
Object.method('superior', function(name) {
  var that = this, method = that[name];
  return function() {
    return method.apply(that, arguments);
  };
});

// Create a new object literal.
var obj = { "one": 1, "two": 2 };

// Enumerate the properties of obj.
for (var property in obj) alert(property);
Instead of enumerating two properties in obj, three are listed: one, two, and superior. Now every object literal in your program will also have a property named superior. Though it may be handy for objects that represent classes, it is inappropriate for ordinary record types.
Makes it impossible to update all instances of a type
In the Closure model, it would be possible to add a field or method to all instances of a type at any point in the program by adding a property to the function constructor's prototype. This is simply not possible in the functional model.

Although this may seem like a minor point, it can be extremely useful when developing or debugging a system to redefine a method on the fly (by using a REPL such as Chickenfoot or the Firebug console). This makes it possible to put probes into a running system rather than having to refresh the entire web page to load changes.

Naming newly created objects is awkward
This may be more of a personal preference, but the "capitalize constructor functions" convention makes it fairly intuitive to name a newly created object. From the pseudoclassical example, we have:
var phone = new Phone('8675309');
where the name of the variable matches that of the constructor, but has a lowercase letter. If the same thing were done in the functional case, it could cause an error:
function callJenny() {
  var phone = phone('8675309');
  makeCall(phone.getPhoneNumber());
}
Here the local variable phone shadows the function phone(), so callJenny() will throw an error when called because phone is bound to undefined when it is applied to '8675209'. Because of this, it is common to add an arbitrary prefix, such as my, to the variable name for newly created objects when using the functional pattern.
Results in an extra level of indentation
Again, this may be more of a personal preference, but requiring the entire class to be defined within a function means that everything ends up being indented one level deeper than it would be when using the Closure paradigm. I concede that this is how things are done in Java, and C# even suggests adding an extra level of depth for good measure with its namespaces, so maybe there's some prize for hitting the tab key a lot that no one told me about. Regardless, if you have ever worked someplace (like Google) where 80-character line limits are enforced, it's nice to avoid line-wrapping where you can.

Potential objections to the pesudoclassical pattern

Won't horrible things happen if I forget the new operator?
If a function with the @constructor annotation is called without the new operator, the Closure Compiler will emit an error. (Likewise, if the new operator is used with a function that does not have the annotation, it will also throw an error.) Crockford's objection that there is no compile-time warning no longer holds! (I find this odd because Crockford could have created his own annotation with an identical check in JSLint.)
Didn't Crockford also say I wouldn't have access to super methods?
Yes, but as the example above demonstrates, a super class's methods are accessible via the superClass_ property added to a constructor function. This property is added as a side-effect of calling goog.inherits(SmartPhone, Phone). Unlike the functional example with super_getDescription, super class accessors do not need to be explicitly created in Closure.
Won't all of the object's properties be public?
It depends on what you mean by "public." All fields and methods of an object marked with the @private annotation will be private in the sense that the Compiler can be configured to reject the input if a private property is being accessed outside of its class. So long as all of the JavaScript in your page is compiled together, the Compiler should preclude any code paths that would expose private data.
Won't declaring SomeClass.prototype for each method and field of SomeClass waste bytes?
Not really. The Compiler will create a temporary variable for SomeClass.prototype and reuse it. As the Compiler works today, it is admittedly most compact to write things in the following style:
SomeClass.prototype = {
  getFoo: function() {
    return this.foo_;
  },

  setFoo: function(foo) {
    this.foo_ = foo;
  },

  toString: function() {
    return '<foo:' + this.getFoo() + '>';
  }
};
However this style has some drawbacks. Doing the above introduces an extra level of indenting and makes reordering methods more tedious because extra care is required to ensure that the last property declared does not have a trailing comma and that all of the other properties do. I think that it is reasonable to expect the Compiler to produce output more similar to the above in the future, but that the recommended input will continue to match the style exemplified in the pseudoclassical example.
I don't need static checks -- my tests will catch all of my errors!
Let's be honest -- do you write tests? And if you are writing tests, how much confidence are they giving you about your code's correctness? As I've discussed previously, existing tools for testing web applications make it difficult to write thorough tests. So even if you have taken the time to write tests, it is unlikely that they exercise all of your code. (Lack of good tools for measuring code coverage by JavaScript tests contributes to the problem.)

By comparision, the Closure Compiler examines your entire program and provides many compile-time checks that can help you find errors before running your code. If Douglas Crockford claims that JSLint will hurt your feelings, then the Closure Compiler will put you into therapy.

"I never knew how sloppy my JavaScript was until I started using the Closure Compiler.
Good grief!"