Definiendo un prototipo de Javascript
¿Cuáles son las diferencias funcionales entre los dos prototipos de Javascript siguientes? ¿Existe algún beneficio al elegir uno sobre el otro?
Opción 1:
Person.prototype.sayName = function(name) {
alert(name);
}
Opcion 2:
Person.prototype = {
sayName: function(name) {
alert(name);
}
}
¿Estoy en lo cierto al suponer que la Opción 2 da como resultado la eliminación de ciertas funciones que están implícitamente vinculadas al prototipo?
¿Estoy en lo cierto al suponer que la Opción 2 da como resultado la eliminación de ciertas funciones que están implícitamente vinculadas al prototipo?
Sí exactamente. Aunque la única propiedad implícitamente vinculada es la constructor
propiedad, que rara vez se necesita.
¿Cuáles son las diferencias funcionales?
La opción 1 es simplemente ampliar el prototipo existente. Si ya hay instancias que heredan del objeto prototipo, también Person
podrán utilizar el método. sayName
Con la opción 2, el nuevo prototipo solo se usará para objetos de los que se creen instancias después de la sobrescritura.
¿Hay algún beneficio por elegir uno sobre el otro?
Estos deberían explicarse por sí solos ahora. La opción 1 (extender) se considera más limpia y es imprescindible si está modificando prototipos extranjeros/desconocidos/nativos. Intente evitar la opción 2.
Si todavía te gusta más la sintaxis literal del objeto, deberías considerar usarla Object.assign
para ampliar el prototipo existente:
Object.assign(Person.prototype, {
sayName: function(name) {
alert(name);
}
});
Es posible que necesites realizar un polyfillObject.assign
para entornos anteriores a ES6. Alternativamente, $.extend
o _.extend
funciona igual de bien. Seguro que tu biblioteca favorita también viene con una función auxiliar para ello.
El segundo sobrescribirá person.prototype con el objeto.
Método uno:
Object.toString=function(){
return "Object to string";
}
var Person = function(){
};
Person.toString=function(){
return "Person to string";
}
Person.prototype.sayName=function(){}
console.log(Person.prototype.constructor.toString());// "Person to string"
Método dos:
Object.toString=function(){
return "Object to string";
}
var Person = function(){
};
Person.toString=function(){
return "Person to string";
}
Person.prototype = {
sayName:function(){}
}
console.log(Person.prototype.constructor.toString());// "Object to string"
El primero sirve para una o dos funciones extra, pero definir un prototipo totalmente nuevo con muchas funciones sería muy repetitivo. Por otro lado, hacer esto último destruiría todas las definiciones existentes para el prototipo como mencionaste.
En la práctica, he usado el primero para definir funciones adicionales en Array y Math, etc., algo así como categorías en Objective-C. Este último lo uso como "definición de clase".
Cualquier instancia existente del constructor seguirá apuntando al antiguo objeto prototipo. Cualquier nueva instancia creada apuntará al nuevo objeto prototipo.
Las ventajas de la opción 1 sobre la opción 2 son simplemente que no es necesario restablecer la propiedad del constructor y se ahorra un nivel de sangría, lo cual es enorme para mí.
Para ahorrar repeticiones, simplemente asigno la propiedad a una variable local:
var method = Person.prototype;
method.getAge = function() {
return this.age;
};
method.getName = function() {
return this.name;
};
También son opciones comunes fn
(jQuery) y p
que son incluso más cortas que method
.