Javascript函数继承与原型

cdm*_*kay 13 javascript performance inheritance prototypal-inheritance

在Douglas Crockford的JavaScript:The Good Parts中,他建议我们使用函数式继承.这是一个例子:

var mammal = function(spec, my) {
    var that = {};
    my = my || {};

    // Protected
    my.clearThroat = function() { 
        return "Ahem";
    };

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

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

    return that;
};

var cat = function(spec, my) {
    var that = {};
    my = my || {};

    spec.saying = spec.saying || 'meow';
    that = mammal(spec, my);

    that.purr = function() { 
        return my.clearThroat() + " purr"; 
    };

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

    return that;
};

var kitty = cat({name: "Fluffy"});
Run Code Online (Sandbox Code Playgroud)

我对此的主要问题是,每次我创建一个mammalcatJavaScript解释器必须重新编译其中的所有函数.也就是说,您无法在实例之间共享代码.

我的问题是:如何提高此代码的效率?例如,如果我制作了数千个cat对象,那么修改此模式以利用该prototype对象的最佳方法是什么?

Ply*_*ynx 8

好吧,如果你打算制作很多mammal或者那么,你就是不能这样做cat.相反,它采用旧式的方式(原型)并通过属性继承.你仍然可以做的建设者你有上述而是的方式thatmy你使用隐式this和代表的基类(在这个例子中,一些变量this.mammal).

cat.prototype.purr = function() { return this.mammal.clearThroat() + "purr"; }
Run Code Online (Sandbox Code Playgroud)

我将使用另一个名称而不是my基本访问,并将其存储thiscat构造函数中.在我使用的这个例子mammal中,如果你想拥有对全局对象的静态访问权限,这可能不是最好的mammal.另一种选择是命名变量base.

  • 如此真实.如果您需要隐私,则需要按惯例执行此操作,例如,在带有下划线的受保护方法之前.如果这看起来太宽松,请考虑即使这种"功能继承"模式本身也是一种惯例.Javascript不是一种"整洁的怪物"语言,它更加"粗糙和准备好".正如你所发现的那样,以整洁的怪异方式工作会使性能受到损失.但是,不要做太多的惩罚 - 考虑到你的例子,它需要数万个对象创建才能显着影响你的整体运行速度. (2认同)
  • "有人可以做`cat.mammal.clearThroat()`并访问受保护的方法" - 并非所有问题都需要通过代码来解决.尽可能尊重,你不是在写Windows.如果有人误用了您的代码,那就太棒了,因为这意味着某人实际上正在使用您的代码.更好地专注于制作有用且易于正确使用的代码,而不是防范假设性问题. (2认同)