【问题标题】:Defining all public methods or prototype individual methods?定义所有公共方法或原型单个方法?
【发布时间】:2011-07-23 04:38:23
【问题描述】:

所以当我创建一个库时,我通常是这样做的:

var myLib = (function() {
    return {
        publicProperty: 'test',
        publicMethod: function() {
            console.log('public function');
        },
        anotherMethod: function() { //... },
        // .. many more public methods
    };
}());

我无意中听说如果你这样写,创建库会更快和/或使用更少的内存进行初始化:

var MyLib = function() {
   this.publicProperty = 'test';
};

MyLib.prototype = {
    publicMethod: function() {
        console.log('public method');
    },
    anotherMethod: function() { //... },
    // ... many more public methods
};

myLib = new MyLib();

一个初始化比另一个快吗?我的问题甚至有意义吗?我假设这些完成了相同的任务(该任务是我在 docready 的代码中的其他地方使用myLib.publicMethod())。谢谢!

【问题讨论】:

  • 在第二个示例中,您不想调用匿名函数。如果您有时间编辑问题,我会相应地编辑我的答案。
  • @Tay Toal,请随时编辑我的主要问题以解决您所说的问题。我真的很感激!
  • 另一个编辑,以确保我们创建了一个 MyLib 的实例

标签: javascript initialization libraries prototype-programming public-method


【解决方案1】:

这两个脚本产生不同的结果。

首先,您创建具有三个(或更多)属性的对象myLib。它的原型是Object.prototype。关键是你做了一个对象。

在第二个中创建一个名为publicProperty 的全局变量。这可能不是你想要的。 (编辑:OP 问题已更正,这不再是问题。)

不过,假设您打算使用原型中的方法创建一个对象,那么您的代码在幼稚的 JavaScript 引擎上可能会更慢,因为在原型中调用方法需要遍历从对象到原型的链接。

现在,如果您的意图不是制作单个,而是制作myLib 的许多实例,那么通过将方法放入原型中,您将节省大量内存,因为您将拥有一个副本每个功能的。你不想要成千上万的方法副本。 :)

编辑以解决 OP 问题

关于这两种方法以及如何使第一种“更快”:

理论上你有一个时空权衡。通过将方法直接放在对象中,您无需原型链查找。但缺点是每个实例都有自己的方法副本。如果要创建多个实例,则应将每个方法定义一次并将它们放在原型中。现代(V8 类)JavaScript 引擎非常适合这种东西,因此您不应该通过将方法打包到对象中来寻找优化速度。现在,对于 singletons,继续填充对象。另一种方法是将所有方法放在myLib 本身中,并使用Object.create(myLib) 创建实例。这使得myLib 本身成为所有“实例”的原型,并且通常被认为是好的形式(至少如果您遵循“好的部分”建议,我通常会这样做)。

【讨论】:

  • 啊好吧。所以在你的最后一段中,你描述了我想要优化的东西。在我的第一个示例中,我创建了大量的公共方法。如何重写第一个示例以更快?
【解决方案2】:

编辑:看看问题的变化,我问你:

  • 您是否计划同时拥有多个库“实例”?

如果你不这样做,我看不出使用构造函数有什么好处,你将只有一个对象,没有必要在其原型上定义属性——它们将被定义并用于单个对象-。

在您想要拥有多个对象实例的情况下,使用继承将很有用,这些方法将被共享、-重用并且只声明一次-在原型链中更高。


您的第二个示例中有几个问题:

var myLib = (function() {
   this.publicProperty = 'this';
}());

myLib 变量将只包含 undefined - 您不会从函数表达式返回任何内容 - 并且您的 publicProperty 将被定义为全局对象的属性,因为您执行此操作的方式函数,this 将绑定到全局对象。

另外,如果代码在strict mode 内执行,那么this 值在这种情况下将为undefined,并且您的属性访问表达式只会抛出TypeError - 这是IMO 的一件好事,因为我'我很确定您不想将publicProperty 声明为全局对象的成员-。

myLib.prototype = {
    publicMethod: function() {
        console.log('public method');
    },
    anotherMethod: function() { //... },
    // ... many more public methods
};

在此处访问prototype 属性将失败-记住,myLibundefined-。

prototype 仅对 函数 有意义,用于 构造函数 - 旨在与 new 运算符一起使用的函数 - 我想你将该属性与所有对象都具有的内部 [[Prototype]] 属性混淆了。

在非函数对象上定义名为prototype 的属性将无效。

另见:

【讨论】:

    猜你喜欢
    • 2011-03-12
    • 1970-01-01
    • 2011-10-20
    • 2012-06-06
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多