Douglas Crockford expressed his preference on creating objects and inheritance in JavaScript In his lecture The Better Parts.
In this lecture he expressed that although prototypal inheritance is better than classical inheritance, but the better is to avoid prototypal inheritance and avoid using this keyword, and instead he introduced a new pattern similar to factory function.
His approach was backed by Eric Elliott in his lecture : Classical Inheritance is Obsolete.
I am going to explain this approach and show some examples on how to use it.

Douglas Crockford new approach

In the lecture he summarized the way of creating objects with this pseudo-code:

function constructor(spec){
  let {member} = spec,

  {other} = other_constructor(spec),

  method = function() {
    // access to member, other, method....
  };

  return Object.freeze({
    method,
    other
  });
}

The above code is just a pseudo-code to express the idea, and the destructuring assignments there are not necessarily going to be implemented by destructuring assignments.
Let us shows an example of using the above code:

var car = function(carSpec) {
  let {maker, year} = carSpec,
  ignite = function() {
    console.log('ignite.....');
  },
  
  getMaker = function() {
    return maker;
  },
  
  getAge = function() {
    return (new Date()).getFullYear() - year;
  };
  
  return {
    ignite,
    getMaker,
    getAge
  };
};

var sedan = function(carSpec) {
  let type = 'Sedan',
      {weels} = carSpec,
      carInfo = car(carSpec),
      drive = function() {
        console.log(`${carInfo.getMaker()} ${type} drive with ${weels} weels`);
      };
  
  return {
    drive,
    carInfo
  }; 
};


var aCar = car({maker: 'Toyota', year: 2004});
console.log(aCar.getMaker());  // Toyota
console.log(aCar.getAge());   // 12

var honda = sedan({maker: 'Honda', year: 2008, weels: 4});

honda.drive();    // "Honda Sedan drive with 4 weels"
honda.carInfo.ignite();  // ignite....

console.log(honda.carInfo.getAge()); // 8

The benefits of the above code:

  • Encapsulation: All variables defined inside the constructor are hidden to the outside, and only accessible by the constructor functions.
  • No worry about the usage of  this  keyword anymore: You don’t have to worry about the context of the function and the usage of this.
  • Code reusage is simpler: No inheritance and long prototype chain to worry about.
  • Match design pattern Composition Over Inheritance: There is a well-known design pattern by the gang of four: Composition Over Inheritance, and this approach embrace it, because we are composing other objects.

What is wrong with prototypal inheritance?

We can list the following challenges with the prototypal inheritance:

  • confusion of who own the property / attribute: Is the property owned by the object or by its prototype? To know that we have to use other functions to know that.
  •  this  keyword can be interpreted differently depending on the caller.
  • Retroactive Heredity: This is a term used by Crockford to describe the complexity that the JavaScript engine has to deal with to keep track of the prototype chain. This explains why the ES6 introduced a new way to set directly the prototype with setPrototypeOf but recommended against using it because of the performance hit that we will encounter.

For all the above reason, and because we have an alternative for creating objects, so Crockford suggesting avoid using prototypal inheritance.

If a feature is sometimes useful and sometimes dangerous and if there is a better option then always use the better option.
Douglas Crockford

When prototypal inheritance is appropriate?

The biggest benefit of prototypal inheritance is Memory Conservation, because prototype objects are created once, and shared among all other objects that reference them as a prototype.
Because nowadays computers and devices become more powerful, and has lots of memory, this feature is arguably untenable when you are doing 90% of programs that need tens or few hundreds of objects. But, when your application is creating hundreds or thousands of the same object over and over, then memory conservation become very reasonable, and you should switch to use the new Class keyword of ES6.