当前位置 : 主页 > 手机开发 > 其它 >

在基于Crockford的功能继承的Javascript中使用超级方法

来源:互联网 收集:自由互联 发布时间:2021-06-19
我一直在阅读Crockford的’The Good Parts’中关于功能继承的章节.在哺乳动物的例子中,他让我有点困惑,为什么他使用上级方法来修改get_name函数.以下是有问题的示例: Function.prototype.metho
我一直在阅读Crockford的’The Good Parts’中关于功能继承的章节.在哺乳动物的例子中,他让我有点困惑,为什么他使用上级方法来修改get_name函数.以下是有问题的示例:

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

var mammal = function (spec) {
    var that = {};

    that.get_name = function () {
        return spec.name;
    };

    that.says = function () {
        return spec.saying || '';
    };

    return that;
};

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

var cat = function (spec) {
    spec.saying = spec.saying || 'meow';
    var that = mammal(spec);

    that.purr = function (n) {
        var i, s = '';
        for (i = 0; i < n; i += 1) {
            if (s) {
                s += '-';
            }
            s += 'r';
        }
        return s;
    };

    that.get_name = function () {
        return that.says() + ' ' + spec.name + ' ' + that.says();
    };

    return that;
};

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

var coolcat = function (spec) {
    var that = cat(spec);
    var super_get_name = that.superior('get_name');

    that.get_name = function (n) {
        return 'like ' + super_get_name() + ' baby';
    };
    return that;
};

var myCoolCat = coolcat({
    name: 'Bix'
});

var name = myCoolCat.get_name(); // 'like meow Bix meow baby'

我对此感到困惑,因为我可以通过删除上级方法并仅更改coolcat来复制相同的内容,如下所示:

var coolcat = function(spec) {
    var that = cat(spec);
    var super_get_name = that.get_name();

    that.get_name = function(n) {
        return 'like ' + super_get_name + ' baby';
    };
    return that;
};

所以,我不明白为什么Crockford选择使用优越的方法.有人能够解释吗?

这里的想法是:

var super_get_name = that.superior('get_name');

使super_get_name成为一个函数 – 每次调用它 – 都会调用它的原始get_name方法.这允许新的get_name调用旧的(超类)get_name.

现在,如果原始的get_name方法除了返回一个永不改变的值之外永远不会有任何影响,那么,这是毫无意义的;你可以保存那个永不改变的单值,然后在新的get_name中使用它.但是,如果原始get_name实际上可以执行某些操作(例如,运行AJAX请求或更改HTML元素的样式),或者其返回值可以更改(例如,如果存在某些相应的set_name方法),那么你的代码所做的事情(保存原始的返回值并使用它)和Crockford的代码之间会有一个重要的区别(保存原始方法并调用它).

网友评论