Definir métodos a través de un prototipo versus usar esto en el constructor: ¿realmente una diferencia de rendimiento?

Resuelto MgSam asked hace 12 años • 7 respuestas

En JavaScript, tenemos dos formas de crear una "clase" y darle funciones públicas.

Método 1:

function MyClass() {
    var privateInstanceVariable = 'foo';
    this.myFunc = function() { alert(privateInstanceVariable ); }
}

Método 2:

function MyClass() { }

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

He leído numerosas veces a personas que dicen que usar el Método 2 es más eficiente ya que todas las instancias comparten la misma copia de la función en lugar de que cada una tenga la suya propia. Sin embargo, definir funciones a través del prototipo tiene una gran desventaja: hace imposible tener variables de instancia privadas.

Aunque, en teoría, el uso del Método 1 le da a cada instancia de un objeto su propia copia de la función (y por lo tanto usa mucha más memoria, sin mencionar el tiempo requerido para las asignaciones), ¿es eso lo que realmente sucede en la práctica? Parece que una optimización que los navegadores web podrían hacer fácilmente es reconocer este patrón extremadamente común y, de hecho, hacer que todas las instancias del objeto hagan referencia a la misma copia de funciones definidas a través de estas "funciones constructoras". Entonces solo podría darle a una instancia su propia copia de la función si se cambia explícitamente más adelante.

Cualquier idea (o, mejor aún, experiencia del mundo real ) sobre las diferencias de rendimiento entre los dos sería de gran ayuda.

MgSam avatar Aug 29 '12 21:08 MgSam
Aceptado

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

Declarar sus métodos a través del prototipo es más rápido, pero es discutible si esto es relevante o no.

Si tiene un cuello de botella en el rendimiento de su aplicación, es poco probable que sea así, a menos que esté creando instancias de más de 10000 objetos en cada paso de alguna animación arbitraria, por ejemplo.

Si el rendimiento es un problema grave y desea microoptimizarlo, le sugeriría declararlo mediante un prototipo. De lo contrario, utilice el patrón que tenga más sentido para usted.

Agregaré que, en JavaScript, existe una convención para anteponer propiedades que deben verse como privadas con un guión bajo (por ejemplo, _process()). La mayoría de los desarrolladores entenderán y evitarán estas propiedades, a menos que estén dispuestos a renunciar al contrato social, pero en ese caso es mejor no atenderlas. Lo que quiero decir es que: probablemente no necesites verdaderas variables privadas...

James avatar Aug 29 '2012 15:08 James

En la nueva versión de Chrome, este método es aproximadamente un 20% más rápido que el método prototipo, pero la creación de un nuevo objeto es aún más lenta.

Si puede reutilizar el objeto en lugar de crear siempre uno nuevo, esto puede ser entre un 50% y un 90% más rápido que crear objetos nuevos. Además del beneficio de no recolectar basura, que es enorme:

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

Yongtao Wang avatar Nov 26 '2015 03:11 Yongtao Wang