性能明智哪个更好:对象原型或构造函数本机函数?

时间:2016-02-08 10:02:43

标签: javascript oop

表现明智什么是更好的做法: 创建原型或将方法添加到构造函数中。

这是我的代码:

function DateGreeting(selector) {
    this.element = document.querySelectorAll(selector)[0];
    this.date = new Date();
    this.hours = this.date.getHours();
    this.greeting = function () {
        if(this.hours <= 11) {
            return "Morning";
        } else if (this.hours >= 12 && this.hours <= 17) {
            return "Afternoon";
        } else {
            return "Evening";
        }
    }
}
DateGreeting.prototype.append = function () {
    this.element.innerHTML = this.greeting();
}

我也可以将this.greeting变成原型,但这会增加性能还是减少它? (或什么都不做..)

我是否应该始终将方法放在原型或构造函数中?

2 个答案:

答案 0 :(得分:2)

工程是一种权衡的游戏。没有普遍最好的解决方案。很高兴进行简单的权衡,就像你在这里一样。答案是:

无论函数/原型的性能影响如何,代码的99%主导部分都是this.element.innerHTML = whatever;。与渲染HTML的成本相比,开销很小。

性能优化成本高昂,通常会导致代码难以理解和维护。大多数情况下,您希望使用最容易理解和简单的方法来执行某些操作,而不是优化性能。了解绩效决策所关注的地方,并了解情况;优化每一件事几乎总是净损失。

至于最佳实践,我很担心Stack Overflow上的那些主题,因为它们总是非常主观并且吸引了非常有见解的答案,不太可能有用。你可以尝试一些编程论坛,或只是阅读一本书或一些文章。

答案 1 :(得分:1)

当创建许多类型为DateGreeting的对象时,所有这些对象都将具有您在构造函数上定义的那些方法的副本。
在处理这些对象时,您通常会更改其属性,但方法保持不变 因此,在原型上声明方法将是一种更节省资源的方法。因此,您可以使用共享相同方法的许多对象,而无需将方法复制到每个实例。
在自定义原型上声明方法肯定更适合性能:

// this method will be shared by all DateGreeting instances
DateGreeting.prototype.greeting = function () {
    if(this.hours <= 11) {
        return "Morning";
    } else if (this.hours >= 12 && this.hours <= 17) {
        return "Afternoon";
    } else {
        return "Evening";
    }
}

var greeting1 = new DateGreeting(".greet");
var greeting2 = new DateGreeting(".greet");
console.log(greeting1, greeting2);
// the output:

output

向构造函数添加方法时会在每个对象实例上创建每个方法的副本:

function DateGreeting(selector) {
    ...
    this.greeting = function () {
        if(this.hours <= 11) {
            return "Morning";
        } else if (this.hours >= 12 && this.hours <= 17) {
            return "Afternoon";
        } else {
            return "Evening";
        }
    }
}

var greeting1 = new DateGreeting(".greet");
var greeting2 = new DateGreeting(".greet");
console.log(greeting1, greeting2);
// the output:

output2