10

这似乎是一个特别模糊的点,但是我正在尝试提高我在整个 Javascript 语言中的基础(更具体地说,它是最好和最有效的实践)。

在http://jsperf.com/中测试理论时,我得出了一些奇怪的结果:

假设我们有两个“相同”的原型,定义如下:

对象1

var Object1 = function() {}

Object1.prototype.defaults = {
    radius: 400,
    up: 1
}

Object1.prototype.centerOffset = function() {
    return this.defaults.radius*this.defaults.up;
}

对象2

var Object2 = function() {}

Object2.prototype = {
    defaults: {
        radius: 400,
        up: 1
    },

    centerOffset: function() {
        return this.defaults.radius*this.defaults.up;
    }
}

在执行以下简单操作时,Object1与Object2相比具有一致(如果边缘:~3%)的速度优势:

var o = new Object1();
var offset = o.centerOffset();

&

var o = new Object2();
var offset = o.centerOffset();

您可以在这里自己运行测试。我在 OSX 10.6.8 上使用 Chrome 25。

我想知道的是:

  • 这种性能差异的原因是什么?
  • 这种性能是否表明了 javascript 中的一些最佳实践?

提前谢谢各位。

编辑:感谢您的回复 - 正如一些人所提到的,我的进一步测试似乎表明这个问题是浏览器(或者更确切地说,特定于 Javascript 编译器)。我还在 Safari、IE 10 和 Firefox 中进行了测试。IE 10 和 Firefox 都给出了非常接近的结果,没有什么不同。Safari 在 Object2 上执行操作的速度比在 Object1 上的稍快(平均约为 2%)。我想知道异常值(其他)是什么,因为这种情况下的性能差异似乎很大。

4

2 回答 2

3

当你声明一个函数时,它的原型属性会被一个包含默认构造函数的对象初始化。

使用 Object1,您正在向现有原型函数添加一个属性。使用 Object2,您正在用您自己的无构造函数替换现有原型。

两者并不相同。

为什么速度不一样?好吧,每次创建实例时,V8 都可以在 object2 原型中添加一个构造函数。

或者更有可能的是,预先存在的原型函数是用机器代码实现的,以使其更快,当您将自己的对象分配给 Object2.prototype 时,原型函数现在是纯 javascript,因此速度较慢。

细节并不那么重要,因为不同的解释器会以不同的方式处理这个问题,重要的是要意识到 Object1 和 Object2 并不完全相同。

于 2013-03-02T20:07:55.507 回答
0

我认为这与您在 Object1 中附加原型并在 Object2 中覆盖它有关。为了验证,我做了第二个性能示例:http: //jsperf.com/correct-way-to-declare-prototype-functions/2

在分配函数之前,我已经添加了“Object1.prototype = {}”。现在 Object1 和 Object2 之间的性能大致相同(至少在 chrome 中)。

于 2013-03-02T19:55:06.007 回答