定义所有公共方法或原型单个方法?

时间:2011-07-23 04:38:24

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

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

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())。谢谢!

2 个答案:

答案 0 :(得分:2)

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

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

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

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

现在,如果您的目的不是为了制作单个但是要制作myLib的许多实例,那么您将通过在原型中添加方法来节省大量内存,因为您将拥有每个功能的一个副本。您不需要数千份方法副本。 :)

编辑解决OP问题

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

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

答案 1 :(得分: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仅对函数有意义,用于构造函数 -functions,用于new运算符 - ,我认为您将该属性与所有对象具有的内部[[Prototype]]属性混淆。

在非函数对象上定义名为prototype的属性将不起作用。

另见: