1

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

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();

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

4

2 回答 2

2

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

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

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

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

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

编辑以解决操作问题

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

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

于 2011-07-23T04:44:54.257 回答
2

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

  • 您是否计划同时拥有您的图书馆的多个“实例”?

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

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


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

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

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

此外,如果代码在严格模式下执行,那么这种情况下的this值将是undefined,并且您的属性访问表达式只会抛出一个TypeError-a 好东西 IMO,因为我很确定您不想声明publicProperty为成员全局对象-。

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

访问prototype这里的属性会失败-记住,myLibundefined-。

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

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

也可以看看:

于 2011-07-23T04:51:30.360 回答