JavaScript函数通过原型或直接引用更快地调用吗?

时间:2011-04-05 00:13:25

标签: javascript performance late-binding prototypal-inheritance function-call

在JavaScript中,假设我想从bObj中调用aObj.myMethod()。对于我的应用程序,从设计的角度来看,aObj是bObj的基类。 JavaScript是一种后期绑定语言,这意味着应该在运行时解析myMethod。功能分辨率是否更快

//////////如果

1 - 我自然地使用我的设计并说bObj.prototype = aObj然后在运行时我调用bObj.myMethod:

function bObj(){...};

bObj.prototype=aObj;


//later
var myBObj=new bObj();
myBObj.myMethod();

//////////////////////// OR

2-函数分辨率可以通过原型缓慢,所以我将aObj作为bObj中的属性保留,并从bObj内部调用aObj.myMethod()

function bObj()
{
  this.myAObj=new aObj();
  ...
}     

//later:
var myBObj=new bObj();
myBObj.myAObj.myMethod();

我主要担心的是执行速度。在我的应用程序中,myMethod每秒被调用数百万次。我知道大多数浏览器都会将指针缓存到最近调用的函数中,所以在这两种情况下都会加速函数解析过程。然而,任何人都可以在这两种情况下提供有关功能解决机制的更多细节,并且可以更深入地了解哪种方法可能更快?解析机制在所有浏览器中是否相同,或者完全取决于浏览器?

2 个答案:

答案 0 :(得分:1)

就你引用的方式而言,“你的功能解决方案可能很慢”。 那么让我们来看看..

在proto chaing查找之后,如果你使myMethod成为一个原型方法,例如:aObj.prototype.myMethod = somemethod,那么第一种方式myBObj.myMethod()将在第二次尝试时获得'解决方案'。它击中了继承的原型方法,因为没有设置myBObj实例myMethod。

第二种方式,myBObj.myAObj.myMethod(),当它碰到原型方法时,会在第二次尝试时得到'分辨率',因为再次没有设置实例方法(myAObj = new aObj()没有设置myAObj.myMethod还会设置myAObj.prototype.myMethod, 所以你这样做的方式没有区别。

通过您执行此操作的方式获得性能提升 要么确保要调用的实例方法已设置,然后引用它:

bObj.myMethod=bObj.prototype.myMethod;
bObj.myMethod();

myAObj.myMethod=myAObj.prototype.myMethod;
bObj.myMethod();

在这两种情况下,第一次查找获取实例方法,并且使用它更好。

要获得最佳性能增益,请完全取消查找 并参考原型方法:

myBobj.prototype.myMethod();

myBObj.myAObj.prototype.myMethod();
在最后两种情况下,

没有'功能解决'是必要的。

虽然我们都知道每次使用时都会解释Function函数 并且声明的函数被编译(解释)一次,因此如果将声明的函数设置为对象的原型实际上使其执行得更快,它仍然有点神秘。

如果你能找到这个,那么你就会知道如何获得一个函数,任何函数, 以最快的速度执行:声明它或将其设置为原型函数,无论哪个最好,如果原型方法更快,则通过直接引用原型方法来避免任何原型链查找。

答案 1 :(得分:0)

我刚刚为这个具体案例完成了几项性能测试。它以Mozilla Rhino 1.7R3运行,处于优化模式。

您的问题实际上是关于财产查询。一旦在可用范围链中找到属性(在您的情况下,具有函数值),在这两种情况下,进一步的操作执行相同。

显而易见的结果是在原型上定义的函数查找速度较慢。平均而言,调用原型函数需要花费35%的时间。直接调用局部函数与直接调用全局范围内的函数,我得到了相同的结果。

自己的属性解决得更快,因为它们的范围在原型之前。

做出决定。请记住,原型非常适合代码维护和对象重用。