1

我试图了解原型函数和嵌套函数之间的区别。我需要知道以下内容

  1. 哪个更好,性能方面
  2. 两者的主要区别是什么
  3. 哪种结构更适合哪种情况(我假设两者都有不同的目标)?

我的基本用法: 我的基本用法是我想为 Web 应用程序编写一个主要功能,当启动时,它将在应用程序导航期间创建菜单、按钮、按钮单击事件、绘制图表、制作表格等,我需要我的代码以更好和最快的方式构建。我将大量使用 jquery 及其插件*

为了简单起见,考虑我需要在可能的应用程序中的许多地方/阶段创建 portlets/widget 容器,我只需调用var port = App.creatPortlet()然后port.content(// place data)

请帮助。

性能: 我在这里创建了性能测试prototype-vs-nested-function,看起来PROTOTYPE函数更快。但我需要一些建议。

原型功能:

  function Person(opt) {
    this.firstName = opt.firstName;
    this.lastName = opt.lastName;
  }

  Person.prototype.getFullName = function() {
    return this.firstName + " " + this.lastName;
  };
 // Testing performance
 var P1 = new Person({
   firstName: 'Jeremy',
   lastName: 'McPeak'
 }).getFullName();

嵌套函数:

var Person = function(opt) {
   return {
     getFullName: function() {
       return opt.firstName + " " + opt.lastName;
     }
   };
 }
 // Testing performance
 var P1 = new Person({
   firstName: 'Jeremy',
   lastName: 'McPeak'
 }).getFullName();

更新: http: //jsperf.com/closure-prototype-static-reveal 我根据我的确切需要创建了 benchamrk。

4

1 回答 1

3

首先,对这么小部分代码的性能测试并不是很有用,因为您不知道这是否会反映实际用例场景中的性能。(您可能会针对该小代码测试 JS 引擎的优化器,例如内联某些方法,或者您触发 JS 引擎的优化过程,该过程需要更长的初始化时间,但会在实时应用程序中带来性能提升,即您检测到测试库的缺陷,....)

我敢打赌,您不会在这里测试原型嵌套函数 ,而是测试两个分配范围处理

查看您的测试,您甚至没有测试这两种情况。您只需测试案例二(在您的准备过程中,您使用 覆盖对 name 函数的访问Personvar Person = ...;因此function Person在您的测试中从未使用过)。它应该看起来像这样:更新 jsperf.com
编辑看起来你在我写作的时候已经改变了自己)。

无论如何,有什么区别,什么更好。两者都有有效的用例,由您决定什么更好。

对象类型

对于第一个,由创建的每个对象Person都是相同的类型:

 var p1 = new Person();
 var p2 = new Person();

 console.log( p1 instanceof Person);  //true
 console.log( p2 instanceof Person);  //true

而在第二个示例中,您创建的每个对象都是Object.
因此,对于他的第一个你,如果对象被传递给另一个函数,你可以测试它是否是 type Person,而对于第二个你不能。

虽然我更喜欢测试特征/功能的存在而不是测试类型,但这对我来说没有任何区别。

原型链

有时更新/扩展所有对象的功能或修改/扩展一种类型的所有对象的现有功能很有用。
虽然这对于第一个示例是可能的,但对于第二个示例是不可能的。

var Person = function() {
};

var p1 = new Person();
Person.prototype.doSomething = function() {console.log("....");};

p1.doSomething();

代码重用

在第一个示例中,您可以在与给定对象相似的对象上重用您的函数。你可以这样做:

Person.prototype.doSomething.call(similarOBject, ...);

在某些情况下这可能很方便。一个经常使用的例子是数组 对象Array上的函数。

保护原始数据

有时保护一些原始数据不被直接读取/修改是有用的。这就是第二个例子的优势。虽然我个人认为这应该由一个好的文档来处理,而不是通过代码强制它,但它仍然是一个有效的用例。在您的示例firstNamelastName,除了创建Person.

性能和速度

哪一个在速度和内存使用上表现更好,主要取决于 JS 引擎。并非每个引擎都会为嵌套函数创建一个新函数,它更有可能被正确检测到并且只是在第二次调用时引用。范围创建会有一些开销,但这可能可以忽略不计,具体取决于对象数和创建它们的频率。

但正如已经说过的,您的代码中很可能会有其他会造成瓶颈的东西。

在大多数情况下,使用prototype是尊重可维护性和可读性的更好选择。

于 2013-10-07T06:34:59.343 回答