通过原型定义方法vs在构造函数中使用它 - 真的是性能差异?

MgS*_*Sam 59 javascript performance memory-management prototype

在JavaScript中,我们有两种方法可以创建"类"并赋予它公共功能.

方法1:

function MyClass() {
    var privateInstanceVariable = 'foo';
    this.myFunc = function() { alert(privateInstanceVariable ); }
}
Run Code Online (Sandbox Code Playgroud)

方法2:

function MyClass() { }

MyClass.prototype.myFunc = function() { 
    alert("I can't use private instance variables. :("); 
}
Run Code Online (Sandbox Code Playgroud)

我读了很多次,人们使用方法2效率更高,因为所有实例共享相同的函数副本而不是每个实例都有自己的副本.通过原型定义函数有一个巨大的缺点 - 它使得无法拥有私有实例变量.

即使理论上,使用方法1给对象的每个实例赋予它自己的函数副本(因此使用更多的内存,更不用说分配所需的时间) - 实际上实际发生了什么?似乎优化Web浏览器可以很容易地识别这种非常常见的模式,并且实际上让对象的所有实例引用通过这些"构造函数"定义的相同函数副本.然后,如果稍后显式更改,它只能为实例提供自己的函数副本.

关于两者之间的性能差异的任何见解 - 或甚至更好的现实世界经验 - 都将非常有帮助.

Jam*_*mes 61

http://jsperf.com/prototype-vs-this

通过原型声明您的方法更快,但这是否相关是值得商榷的.

如果您的应用程序中存在性能瓶颈,则不太可能出现这种情况,例如,除非您碰巧在某些任意动画的每一步中实例化10000多个对象.

如果性能是一个严重的问题,并且你想进行微优化,那么我建议通过原型声明.否则,只需使用对您最有意义的模式.

我将补充一点,在JavaScript中,有一种前缀属性的约定,这些属性旨在被视为私有的下划线(例如_process()).大多数开发人员会理解并避免这些属性,除非他们愿意放弃社会契约,但在这种情况下,你可能也不会满足于他们.我的意思是说:你可能真的不需要真正的私有变量......

  • 这在2016年仍然适用吗? (4认同)
  • @RajV,原型方法只声明一次.内部函数(非原型)需要在每个实例化时声明 - 我认为这是使这种方法变慢的原因.正如你所说,调用方法实际上可能更快. (3认同)
  • @RajV,你的测试在每次迭代时仍在运行'new T`.JSperf站点将自动测试您的代码段数百万次.您不需要添加自己的循环.看到这里:http://jsperf.com/prototype-vs-this/3 ......结果看起来是一样的.原型方法调用稍快,这很奇怪. (2认同)