Javascript原型与一般功能 - 性能/可读性

时间:2012-09-02 17:17:54

标签: javascript prototype

所以我写了这些测试,看看使用原型会有多快......

function User() {
    return {
        name: "Dave",
        setName: function(n) {
            this.name = n;
        },
        getName: function() {
            return this.name;
        }
    };
}

function UserPrototype() {
    if (!(this instanceof UserPrototype)) return new UserPrototype();
    this.name = "Dave";
}
UserPrototype.prototype.getName = function() {
    return this.name;
};
UserPrototype.prototype.setName = function(n) {
    this.name = n;
};

function setName(obj,name)
{
    obj.name = name;
}
function getName(obj)
{
    return obj.name;
}

//Test 1
var c = 10000000;
var tstart = 0;
var tend = 0;
tstart = new Date().getTime();
for (var j = 0; j < c; j++) {
    var newUser = User();
    newUser.setName("michael");
    newUser.getName();
}
tend = new Date().getTime() - tstart;
console.log("Returning object with methods: " + tend / 1000.0 + " seconds");
//Test 2
tstart = new Date().getTime();
for (var j = 0; j < c; j++) {
    var newUser = new UserPrototype();
    newUser.setName("michael");
    newUser.getName();
}
tend = new Date().getTime() - tstart;
console.log("Using prototypes: " + tend / 1000.0 + " seconds");
//Test 3
tstart = new Date().getTime();
for (var j = 0; j < c; j++) {
    var newUser = {name:"dave"};
    setName(newUser,"michael");
    getName(newUser);
}
tend = new Date().getTime() - tstart;
console.log("Using general functions: " + tend / 1000.0 + " seconds");
​

我的结果:

Returning object with methods: 9.075 seconds
Using prototypes: 0.149 seconds 
Using general functions: 0.099 seconds 

我编写了前两个测试,当我看到结果时,我想到了为什么我会看到它们......我想的原因是返回的对象很慢,因为有两个新的方法属性实例是每次实例化对象时创建,而原型方法更快,因为它只创建一次函数。一般函数调用和原型之间的性能接近使我认为我的假设是正确的。

所以我的第一个问题是,我对我的假设是对的吗?

我的第二个问题是,如何使原型的写作更具可读性,同时保持高性能?有没有办法以一种看起来像是在“类”中的方式对原型进行编码(如果这样做有意义的话)

*编辑 - 我忘了用Object.create()做测试,只做了一个并发布结果。 JSFiddle :( http://jsfiddle.net/k2xl/SLVLx/)。

我现在开始:

Returning object with methods: 0.135 seconds fiddle.jshell.net:63
Using prototypes: 0.003 seconds fiddle.jshell.net:72
Using general functions: 0.002 seconds fiddle.jshell.net:81
Returning object.create version: 0.024 seconds 

看起来这可能是解决方案吗?

2 个答案:

答案 0 :(得分:3)

我同意你的假设。如果代码是这样编写的,那么这也是很难理解的:

function UserObject() {
    this.name = "Dave";

    this.getName = function() {
        return this.name;
    };
    this.setName = function(n) {
        this.name = n;
    };
}

在这种情况下,就像在“对象”方法中一样,每次构造getName对象时都会创建setNameUserObject方法。

“原型”和“函数”方法之间的代码略有不同。删除if (!(this instanceof UserPrototype)) return new UserPrototype();(这是一个不必要的安全防范)会刮掉相当多的东西。可以说,与......进行更密切的比较......

var newUser = new UserPrototype();
[newUser].name = "Dave";

......是......

var newUser = new Object();
newUser.name = "dave";

...因为......

var newUser = {name:"dave"};

...在创建Object并添加name属性时,可以使用本机代码。

在这种情况下,结果会翻转,“原型”方法会更快出现。在这里看一个jsFiddle:

关于如何使原型更具可读性,我无能为力。对我来说,它们是可读的: - )

答案 1 :(得分:0)

当你在构造函数中没有使用这个值时,永远不要在构造函数中使用它,而是作为原型使用它。 E.g。

UserPrototype.prototype.name =“Dave”;

当你这样做时,原型在速度上获胜。