2008-08-09 13 views
16

Hay algunas maneras de conseguir un comportamiento de clase similar en javascript, los más comunes parecen ser prototipo basado así:¿Qué estilo usas para crear una "clase"?

function Vector(x, y, x) { 
    this.x = x; 
    this.y = y; 
    this.z = z; 
    return this; 
} 

Vector.prototype.length = function() { return Math.sqrt(this.x * this.x ...); } 

y los enfoques basados ​​cierre similar a

function Vector(x, y, z) { 
    this.length = function() { return Math.sqrt(x * x + ...); } 
} 

Por diversas razones este último es más rápido, pero he visto (y con frecuencia escribo) la versión del prototipo y sentía curiosidad por saber qué hacen otras personas.

+0

Mis pruebas han demostrado que el enfoque basado en el cierre es más lento. Debe instanciar un cierre por separado para cada objeto. El enfoque prototipo comparte los métodos con todas las instancias. –

Respuesta

9

La asignación de funciones al prototipo es mejor (para los métodos públicos) porque todas las instancias de la clase compartirán la misma copia del método. Si asigna la función dentro del constructor como en el segundo ejemplo, cada vez que crea una nueva instancia, el constructor crea una nueva copia de la función de longitud y la asigna a esa única instancia.

Sin embargo, esta última técnica es útil si desee cada copia a tener su copia propia, el uso principal de ese ser que ver métodos/privilegios privados que tienen acceso a las variables privadas declaradas dentro del constructor y heredados a través del cierre mecanismo.

Douglas Crockford tiene un buen summary.

2

Bueno, realmente no tengo una opinión experta sobre esto. Suelo terminar usando el enfoque basado en cierres solo porque mantiene el código más simple para el administrador. Pero, me he encontrado utilizando prototipos para métodos que tienen muchas líneas de código.

2

También tiene la opción de:

function Vector(x, y, z) { 
    function length() { 
    return Math.sqrt(x * x + ...); 
    } 
} 

Cuál es, probablemente, tan lento como ejemplo dos, pero se ve más como Java/C# y es un poco más explícito.

3

Afortunadamente llego a usar prototype.js, que proporciona algunas envolturas agradables. Así que usted puede hacer esto:

var Person = Class.create({ 
    initialize: function(name) { 
     this.name = name; 
    }, 
    say: function(message) { 
     return this.name + ': ' + message; 
    } 
}); 

Prototype.js Documentation: Defining classes and inheritance

+0

No creo que OP haya pedido un contenedor que oculte los detalles. Quería saber por qué elegiría cualquiera de los enfoques, por lo que puede sopesar los beneficios –

4

Existe también el enfoque literal objeto para el prototipo:

var Vector = function(){}; 

Vector.prototype = { 
    init:function(x,y,z) { 
    this.x = x; 
    this.y = y; 
    this.z = z; 
    }, 
    length:function() { 
    return Math.sqrt(x * x + ...); 
    } 
}; 

var v1 = new Vector(); 
v1.init(1,2,3); 
+0

No puede establecer el prototipo literal si está heredando de otra cosa, que anularía el prototipo anterior –

+0

Tiene razón, pero en este caso, "Vector" es un objeto nuevo, por lo que no vi ninguna necesidad de preocuparse por los problemas de herencia – JayTee

1

Soy un gran fan de la utilización de este John Resig's library. Ligero, directo, y usted ya sabe cómo usarlo si está familiarizado con el estilo 'habitual' orientado a objetos.

1

No hay clases en javascript.

Sin embargo, hay objetos. No necesita una clase para crear un objeto en javascript.Se tiene funciones Constuctor importantes que pueden ejecutarse con el nuevo, por ejemplo:

var james = new Person(); 

Puede simular clase como el comportamiento con:

prototipo ejemplo:

function Car (type) { 
    this.type = type; 
    this.color = "red"; 
} 

Car.prototype.getInfo = function() { 
    return this.color + ' ' + this.type + ' car'; 
}; 

objeto ejemplo literal

var car = { 
    type: "honda", 
    color: "red", 
    getInfo: function() { 
     return this.color + ' ' + this.type + ' car'; 
    } 
} 
Cuestiones relacionadas