Using super methods in Javascript based on Crockford's functional inheritance

后端 未结 2 1183
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-13 16:36

I\'ve been reading the chapter on functional inheritance in Crockford\'s \'The Good Parts\'. In the mammal example he gives I\'m a bit confused as to why he uses the s

2条回答
  •  自闭症患者
    2021-01-13 17:32

    The confusion that arises from this chapter of Crockford's book arises as what Crockford describes is "his" preferred pattern for implementing inheritance in JavaScript, which relies on his extending the Function object with the Function.prototype.method (chapter 1.3) which he uses to add methods to the Function object.

    The problem addressed in the coolcat example is the need to access the method of the parent type. In 'classical' OO languages like Java this is natural as classes exist in their own right. In JavaScript inheritance is prototypical, you make an object of type mammal and then modify the object to create the type cat or coolcat.

    Depending on your design you may add properties and functions or override an 'inherited' function. The problem arises when you override an 'inherited' function, in JavaScript you basically replace the old function with the new function, thereby loosing the older function.

    Crockford now needs to do two things:

    1. get the parent's (cat's) get_name method; and
    2. save it in a manner that can be used from within the overridden method.

    In this code:

    var coolcat = function(spec) {
        var that = cat(spec), 
            super_get_name = that.superior('get_name');
        that.get_name = function(n) {
            return 'like ' + super_get_name() + ' baby';
        };
        return that;
    };
    

    He does 1. by calling the superior method to get a function that gets the cat's get_name function; and he does 2. by saving it to the super_get_name variable within the coolcat function(/object) allowing access to the cat's get_name function before it is overridden (more correctly overwritten) by the coolcat's get_name function.

    In my opinion the confusion arises because:

    1. The superior method is named oddly: the 'superior' method is simply a function look up by name method and could be better named, for example as getFunctionByName (you can try this by replacing the string get_name, by purr, the coolcat's get_name will now call purr, just remember to call it as super_get_name(10) otherwise you'll get an empty string back).
    2. Secondly the code and the pattern obfuscates the code by relying on some particular Crockford patterns, and is likely to stresses you out if you attempt to dive into this chapter without having followed the entire book.

    I think there is a simpler way to achieve this, one that I think because it is completely localized is easier to understand etc., as in the code below:

    var coolcat = function(spec) {
        var that = cat(spec);
        that.parent_get_name = that.get_name;
        that.get_name = function() {
           return 'like ' + this.parent_get_name() + ' baby';
        };
        return that;
    };
    

    There are some other oddities for example the argument n in definition of the coolcat get_name function, which I can only assume came from copying the purr function, which would suggest a ghost writer!

    Finally, I would suggest that before one reads the book one should listen to his talk on 'JavaScript the good parts'. The talk is absolutely brilliant, much better than the book.

提交回复
热议问题