javascript. Наследование

В одной из статей - Javascript. Object oriented programming. Object literal - были затронуты вопросы применения ООП подходов в javascript. Ниже приведено дополнение этой темы и касаться оно будет вопроса наследования.
У Дугласа Крокфорда есть замечательная книжка - "JavaScript. Сильные стороны". В ней собрано очень много полезных советов касательно использования javascript, очень советую. Итак, Дуглас выделяет три вида наследования. Рассмотрим каждый из них.

1. Псевдоклассовое насследование

Как Вы уже знаете, в javascript реализация классов носит условный характер (поэтому и псевдоклассовое наследование). В данном случае первоначально создаются конструкторы, содержимое которых увязываются через прототипы.

var Mammal = function(name) {
    this.name = name;
};

Mammal.prototype.getName = function() {
    return this.name;
};

Mammal.prototype.says = function() {
    return this.saying || '';
};

var Cat = function (name) {
    this.name = name;
    this.saying = 'meow';
};

Cat.prototype = new Mammal();

Cat.prototype.getName = function () {
    return this.says() + ' ' + this.name + ' ' + this.says();
};

var myMammal = new Mammal('Herb');
var myCat = new Cat('Henrietta');

console.log(myMammal.getName()); // Herb 
console.log(myMammal.says()); //

console.log(myCat.getName()); // meow Henrietta meow
console.log(myCat.says()); // meow


2. Прототипизированное насследование

В данном случае, работа идет с объектами, это иной подход. чем в классическом виде наследования. Сначала создается ряд полезных объектов и далее на основе этих объектов строятся другие объекты.

if (typeof Object.create !== 'function') {
    Object.create = function(o) {
        var F = function() {};
        F.prototype = o;
        return new F();
    };
}

var myMammal = {
    name: 'Herb the Mammal',
    getName: function() {
        return this.name;
    },
    says: function() {
        return this.saying || '';
    }
};

var myCat = Object.create(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'meow';
myCat.getName = function() {
    return this.says() + ' ' + this.name + ' ' + this.says();
};

console.log(myMammal.getName()); // Herb 
console.log(myMammal.says()); //

console.log(myCat.getName()); // meow Henrietta meow
console.log(myCat.says()); // meow


3. Функциональное наследование

В данном случае объекты создаются на основе функций, так как от них мы не инстанцируемся, то это позволяет нам отказаться от использования this во внутренних реализациях, что позволяет нам получать более надежные и более защищенные объекты (так как очень просто добавлять скрытые данные внутри этих функций) 

var mammal = function(obj) {
    var that = {};
   
    that.getName = function() {
        return obj.name;
    };
   
    that.says = function() {
        return obj.saying || '';
    };
   
    return that;
};

var cat = function(obj) {
    obj.saying = obj.saying || 'meow';
    var that = mammal(obj);
   
    that.getName = function() {
        return that.says() + ' ' + obj.name + ' ' + that.says();
    };
    return that;
};

var myMammal = mammal({name: 'Herb'});
var myCat = cat({name: 'Henrietta'});

console.log(myMammal.getName()); // Herb 
console.log(myMammal.says()); //

console.log(myCat.getName()); // meow Henrietta meow
console.log(myCat.says()); // meow