2009-10-28 7 views
427

¿Cuál es la diferencia entre las siguientes dos declaraciones?JavaScript: Class.method vs. Class.prototype.method

Class.method = function() { /* code */ } 
Class.prototype.method = function() { /* code using this.values */ } 

¿Se puede pensar en la primera declaración como una declaración de un método estático, y la segunda declaración como una declaración de un método de instancia?

Respuesta

630

Sí, la primera función no tiene relación con una instancia de objeto de ese constructor function, se puede considerar como un 'método estático'.

En funciones de JavaScript son objetos first-class, eso significa que se pueden tratar como cualquier objeto, en este caso, sólo se va a agregar una propiedad al objeto función.

La segunda función, al extender el prototipo de función de constructor, estará disponible para todas las instancias de objeto creadas con la palabra clave new, y el contexto dentro de esa función (la palabra clave this) se referirá a la instancia de objeto real donde lo llamas.

Considere este ejemplo:

// constructor function 
function MyClass() { 
    var privateVariable; // private member only available within the constructor fn 

    this.privilegedMethod = function() { // it can access private members 
    //.. 
    }; 
} 

// A 'static method', it's just like a normal function 
// it has no relation with any 'MyClass' object instance 
MyClass.staticMethod = function() {}; 

MyClass.prototype.publicMethod = function() { 
    // the 'this' keyword refers to the object instance 
    // you can access only 'privileged' and 'public' members 
}; 

var myObj = new MyClass(); // new object instance 

myObj.publicMethod(); 
MyClass.staticMethod(); 
+53

Esto fue tomado de: http://code.google.com/intl/es/speed/articles/optimizing-javascript.html También es importante decir que si estamos creando muchas instancias de 'MyClass', estamos creando para cada instancia una función' privilegedMethod'. Sin embargo, 'publicMethod' solo se construye una vez para todas las instancias creadas. – Menda

+13

Aquí hay un enlace actualizado al artículo mencionado en el comentario de Menda: https://developers.google.com/speed/articles/optimizing-javascript –

+1

¿Pero por qué es Function.prototype.method == Function.method? – Raghavendra

15

Al crear más de una instancia de MyClass, todavía sólo tienen sólo una instancia de publicMethod en la memoria, pero en el caso de privilegedMethod el resultado final será la creación de una gran cantidad de casos y staticMethod no tiene relación con una instancia de objeto.

Es por eso que los prototipos ahorran memoria.

Además, si cambia las propiedades del objeto principal, no se ha modificado la propiedad del elemento secundario, se actualizará.

5

para los estudiantes visuales, en la definición de la función sin .prototype

ExampleClass = function(){}; 
ExampleClass.method = function(customString){ 
      console.log((customString !== undefined)? 
          customString : 
          "called from func def.");} 
ExampleClass.method(); // >> output: `called from func def.` 

var someInstance = new ExampleClass(); 
someInstance.method('Called from instance'); 
    // >> error! `someInstance.method is not a function` 

Con mismo código, si se añade .prototype,

ExampleClass.prototype.method = function(customString){ 
      console.log((customString !== undefined)? 
          customString : 
          "called from func def.");} 
ExampleClass.method(); 
     // > error! `ExampleClass.method is not a function.` 

var someInstance = new ExampleClass(); 
someInstance.method('Called from instance'); 
       // > output: `Called from instance` 

Para hacer i t más clara,

ExampleClass = function(){}; 
ExampleClass.directM = function(){} //M for method 
ExampleClass.prototype.protoM = function(){} 

var instanceOfExample = new ExampleClass(); 

ExampleClass.directM();  ✓ works 
instanceOfExample.directM(); x Error! 

ExampleClass.protoM();  x Error! 
instanceOfExample.protoM(); ✓ works 

**** Nota para el ejemplo anterior, someInstance.method() no se ejecutará como,
ExampleClass.method() hace que la ejecución error & no puede continuar.
Pero en aras de la ilustración & fácil comprensión, he mantenido esta secuencia. ****

resultados son generados de chrome developer console & JS Bin
Haga clic en el enlace de arriba para jsbin recorrer el código.sección
Toggle comentó con ctrl + /