Autor Tema: JavaScript diferencia entre call y apply para qué sirve ejemplo código CU01150E  (Leído 2870 veces)

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Buenos días.

Aquí dejo las posibles soluciones de los ejercicios de la entrega CU01150E del curso JavaScript desde cero.

Citar
EJERCICIO 1

Crea un esquema de herencia que cumpla con estos requisitos:

a) Un Médico especialista tiene una especialidad y es un tipo de Médico.

b) Un Médico trabaja en un centro de trabajo y es un tipo de Persona.

c) Una Persona tiene un nombre y una nacionalidad. Como método común a todas las personas tenemos mostrarNacionalidad, que muestra un mensaje informando de la nacionalidad.

Se desea crear un objeto de tipo MedicoEspecialista pasándole como parámetros para su creación además de sus propiedades intrínsecas las propiedades que hereda de sus supertipos y sobre este objeto invocar el método mostrarNacionalidad(), que deberá ser reconocido por herencia.

Posible código de este ejercicio sería:

Código: [Seleccionar]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ejemplo aprenderaprogramar.com</title>
<script type="text/javascript">

function Persona(centro){
this.centro = centro || 'Desconocida';
}

function PersonaConNacionalidad(nombre,nacionalidad){
this.nombre = 'Juan';
this.nacionalidad = 'del mundo';
this.saludar = function(nacionalidad){
alert('Esta es mi nacionalidad: '+this.nacionalidad);
}
}

function MedicoEspecialista(especialidad,centro,nombre,nacionalidad){
this.especialidad = especialidad;
Persona.call(this,centro);
PersonaConNacionalidad.apply(this,[nombre,nacionalidad]);
}
MedicoEspecialista.prototype = new PersonaConNacionalidad();

function ejemploObjetos(){
var unMedico = new MedicoEspecialista('ortopedia','Hospital del Mar','Joan','del mundo');
alert('Hola, mi especialidad es: '+unMedico.especialidad+' trabajo en: '+unMedico.centro);
unMedico.saludar();
}

</script>
</head>
<body>
<div id="cabecera">
<h2>Cursos aprenderaprogramar.com</h2>
<h3>Ejemplos JavaScript</h3>
</div>
<div style="color:blue;" id ="pulsador" onclick="ejemploObjetos()"> Probar Ejercicio</div>
</body>
</html>

El segundo ejercicio exigía lo siguiente:

Citar
EJERCICIO 2

Crea un código que represente el siguiente esquema de herencia permitiendo instanciar los subtipos pasándole los parámetros necesarios para inicializar las propiedades de los supertipos. Crea un objeto ProfesorTitular profesorTitular1 al que le pases como parámetros 8 (años trabajados), Universidad de León (institución académica), Juan (nombre),  e invoca el método saludar sobre este objeto.

Y la solución que he encontrado es:

Código: [Seleccionar]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ejemplo aprenderaprogramar.com</title>
<script type="text/javascript">

function Persona(nombre){
this.nombre=nombre;
this.saludar=function(){
alert('Hola, soy '+this.nombre);
}
}
Persona.prototype.definicion='Definicion';

function Profesor(){
this.institucionAcademica=institucionAcademica;
}

function ProfesorInterino(mesesContrato){
this.mesesContrato=mesesContrato;
}

function ProfesorTitular(añosTrabajados,institucionAcademica,nombre){
this.añosTrabajados=añosTrabajados;
Persona.call(this,nombre)
}
ProfesorTitular.prototype = new Persona();

function ejemploObjetos(){
var unProfesor = new ProfesorTitular(8,'Universdidad de León','Juan');
var unInterino = new ProfesorInterino(9);
unProfesor.saludar(); 
}

</script>
</head>
<body>
<div id="cabecera">
<h2>Cursos aprenderaprogramar.com</h2>
<h3>Ejemplos JavaScript</h3>
</div>
<div style="color:blue;" id ="pulsador" onclick="ejemploObjetos()"> Probar Ejercicio</div>
</body>
</html>

Otra posible solución, creo que sería la siguiente:

Código: [Seleccionar]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ejemplo aprenderaprogramar.com</title>
<script type="text/javascript">

function Persona(nombre){
this.nombre=nombre;
this.saludar=function(){
alert('Hola, soy '+nombre);
}
}
Persona.prototype.definicion='Definicion';

function Profesor(){
this.institucionAcademica=institucionAcademica;
}

function ProfesorInterino(mesesContrato){
this.mesesContrato=mesesContrato;
}

function ProfesorTitular(añosTrabajados,institucionAcademica,nombre){
this.añosTrabajados=añosTrabajados;
Persona.call(this,nombre)
}
ProfesorTitular.prototype = new Persona();

function ejemploObjetos(){
var unProfesor = new ProfesorTitular(8,'Universdidad de León','Juan');
var unInterino = new ProfesorInterino(9);
unProfesor.saludar(this,'Juan');
}

</script>
</head>
<body>
<div id="cabecera">
<h2>Cursos aprenderaprogramar.com</h2>
<h3>Ejemplos JavaScript</h3>
</div>
<div style="color:blue;" id ="pulsador" onclick="ejemploObjetos()"> Probar Ejercicio</div>
</body>
</html>

Gracias.

« Última modificación: 24 de Febrero 2016, 09:51 por César Krall »

bermartinv

  • Avanzado
  • ****
  • APR2.COM
  • Mensajes: 298
    • Ver Perfil
Re:CU01150E JavaScript call, Diferencia con apply
« Respuesta #1 en: 20 de Febrero 2016, 16:02 »
Para el ejercicio1:
Lo normal es que uses call en vez de apply. Apply se usa cuando el segundo parametro es un vector que tiene varios valores, en nuestro caso son variables que estan definidas y no son vectores ninguna de las dos.
El objeto Persona debe definir las características nombre y nacionalidad y un METODO COMÚN que muestre la cionalidad (recuerda con prototype).
Te falta añadir la variable centro a los objetos PersonaConNacionalidad y en MedicoEspecialista. Te paso tu codigo con esto modificado y así funcionaría pero debes definir otra vez lo objetos no te has ceñido a la definición que ponia el ejercicio, como te he comentado antes.
Código: [Seleccionar]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ejemplo aprenderaprogramar.com</title>
<script type="text/javascript">

function Persona(centro){
this.centro = centro || 'Desconocida';
}

function PersonaConNacionalidad(nombre,nacionalidad,centro){
this.nombre = 'Juan';
this.nacionalidad = 'del mundo';
this.saludar = function(nacionalidad){
alert('Esta es mi nacionalidad: '+this.nacionalidad);
};
            Persona.call(this,centro);
}
        PersonaConNacionalidad.prototype = new Persona();

function MedicoEspecialista(especialidad,centro,nombre,nacionalidad){
this.especialidad = especialidad;
PersonaConNacionalidad.call(this,nombre,nacionalidad,centro);
}
MedicoEspecialista.prototype = new PersonaConNacionalidad();

function ejemploObjetos(){
var unMedico = new MedicoEspecialista('ortopedia','Hospital del Mar','Joan','del mundo');
alert('Hola, mi especialidad es: '+unMedico.especialidad+' trabajo en: '+unMedico.centro);
unMedico.saludar();
}

</script>
</head>
<body>
<div id="cabecera">
<h2>Cursos aprenderaprogramar.com</h2>
<h3>Ejemplos JavaScript</h3>
</div>
<div style="color:blue;" id ="pulsador" onclick="ejemploObjetos()"> Probar Ejercicio</div>
</body>
</html>


bermartinv

  • Avanzado
  • ****
  • APR2.COM
  • Mensajes: 298
    • Ver Perfil
Re:CU01150E JavaScript call, Diferencia con apply
« Respuesta #2 en: 20 de Febrero 2016, 16:09 »
Del segundo ejercicio,
vuelvelo a repasar porque las herencias no están bien hechas.
Tu objeto ProfesorTitular hereda de Persona, pero no hereda nada del objeto Profesor.
Tiene que heredar de Profesor, y Profesor heredar de Persona.

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Re:CU01150E JavaScript call, Diferencia con apply
« Respuesta #3 en: 20 de Febrero 2016, 18:21 »
Cuelgo el código del segund ejercicio:

Recuerdo lo que pedía el ejercicio:

Citar
EJERCICIO 2

Crea un código que represente el siguiente esquema de herencia permitiendo instanciar los subtipos pasándole los parámetros necesarios para inicializar las propiedades de los supertipos. Crea un objeto ProfesorTitular profesorTitular1 al que le pases como parámetros 8 (años trabajados), Universidad de León (institución académica), Juan (nombre),  e invoca el método saludar sobre este objeto.

Código: [Seleccionar]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ejemplo aprenderaprogramar.com</title>
<script type="text/javascript">

function Persona(){
this.nombre='Juan';
this.saludar=function(){
alert('Hola, soy '+this.nombre);
}
}
Persona.prototype.definicion='Definicion';

function Profesor(){
this.institucionAcademica='Hospital';
}
Profesor.prototype = new Persona();

function ProfesorInterino(mesesContrato){
this.mesesContrato=mesesContrato;
}
ProfesorInterino.prototype = new Profesor();

function ProfesorTitular(añosTrabajados){
this.añosTrabajados=añosTrabajados;
}
ProfesorTitular.prototype = new Profesor();

function ejemploObjetos(){
var unProfesor = new ProfesorTitular(8);
var unInterino = new ProfesorInterino(9);
unProfesor.saludar(); 
}

</script>
</head>
<body>
<div id="cabecera">
<h2>Cursos aprenderaprogramar.com</h2>
<h3>Ejemplos JavaScript</h3>
</div>
<div style="color:blue;" id ="pulsador" onclick="ejemploObjetos()"> Probar Ejercicio</div>
</body>
</html>

Es así?




bermartinv

  • Avanzado
  • ****
  • APR2.COM
  • Mensajes: 298
    • Ver Perfil
Re:CU01150E JavaScript call, Diferencia con apply
« Respuesta #4 en: 20 de Febrero 2016, 23:12 »
Es casi así dimiste,
pero repasa este ejercicio ya resuelto en este foro:
https://www.aprenderaprogramar.com/foros/index.php?topic=3390.msg14834#msg14834
https://www.aprenderaprogramar.com/foros/index.php?topic=3968.msg16795#msg16795
Como puedes ver, cuando creas un nuevo objeto de profesorTitular o profesorInterino, se crea nombrando todas las variables que hemos enlazado con los distintos objetos :
por ejemplo:
profesorTitular(anyostrabajados,institucionacademica,nombre)
profesorInterino(mesesContrato,institucionacademica,nombre)

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Re:CU01150E JavaScript call, Diferencia con apply
« Respuesta #5 en: 21 de Febrero 2016, 17:34 »
Gracias, bermartinv.

Creo que me ha quedado claro el tema. De todas maneras, si tengo más dudas, os lo preguntaré, que me he dado cuenta que sois personas amables y puedo contar con vuestra ayuda.

Sólo una cuestión, en el código siguiente (que es de tu enlace):

Código: [Seleccionar]
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
<script>
   
function persona(nombre){
    this.nombre = nombre || 'desconocido';
    this.saludar = function(mastexto){
        alert ('Te saluda ' +this.nombre+ ' que trabaja en '+this.institucionAcademica+mastexto);
    }
}
persona.prototype.definicion = 'Una persona es un ser vivo que tiene conocimiento';
   
function profesor(institucionAcademica,nombre){
    this.institucionAcademica = institucionAcademica || 'desconocida';
    persona.call(this,nombre);
}
profesor.prototype = new persona();
   
function profesorInterino(mesesContrato,institucionAcademica,nombre){
    this.mesesContrato = mesesContrato || 0;
    profesor.call(this,institucionAcademica,nombre);
}
profesorInterino.prototype = new profesor();

function profesorTitular(anyosTrabajados,institucionAcademica,nombre){
    this.anyosTrabajados = anyosTrabajados || 0;
    profesor.call(this,institucionAcademica,nombre);
}
profesorTitular.prototype = new profesor();


function crearObjeto(){
    profesorTitular1 = new profesorTitular(8,'Universidad de Leon','Juan');
    alert(profesorTitular1.definicion);
    profesorTitular1.saludar(' y lleva '+profesorTitular1.anyosTrabajados+' anyos trabajados');
}

    </script>
</head>
<body>
   <button onclick="crearObjeto()">Profesor Titular</button>
   
</body>
</html>

En la función:

Código: [Seleccionar]
function profesorInterino(mesesContrato,institucionAcademica,nombre){
    this.mesesContrato = mesesContrato || 0;
    profesor.call(this,institucionAcademica,nombre);
}
profesorInterino.prototype = new profesor();

de dónde se le pasa la información de las variablels "institucionAcademica" y "nombre"?
Al principio, al crea el objeto "new profesorTitular" sólo se le pasas a la misma, pero dentro de ella no llamas a la función "profesorInterino" para pasarle los parámetros. Quiero decir, no debería de ser la función "profesorTitular" así:

Código: [Seleccionar]
function profesorTitular(anyosTrabajados,institucionAcademica,nombre){
    this.anyosTrabajados = anyosTrabajados || 0;
    profesor.call(this,institucionAcademica,nombre);
    profesorInterino.call(institucionesAcademica,nombre);
}

en vez de así:

Código: [Seleccionar]
function profesorTitular(anyosTrabajados,institucionAcademica,nombre){
    this.anyosTrabajados = anyosTrabajados || 0;
    profesor.call(this,institucionAcademica,nombre);
}
 
 
Y en la función "profesorInterino" por qué le pasas un parámetro vacío si lo inicias en la misma funcio? Es decir, no debería de ser así:

Código: [Seleccionar]
function profesorInterino(institucionAcademica,nombre){
    this.mesesContrato = 'valorInicializadoAquí';
    profesor.call(this,institucionAcademica,nombre);
}

en vez de así:

Código: [Seleccionar]
function profesorInterino(mesesContrato,institucionAcademica,nombre){
    this.mesesContrato = mesesContrato || 0;
    profesor.call(this,institucionAcademica,nombre);
}

Ya te digo, bermartinv, no te estoy corregiendo, sino que estoy intentando aclararme el lío que tengo en la cabeza con las herencia.

Además, creo que el concepto de "herencia" no es muy adecuado para este tipo de métodos. Yo le llamaría, más bien, pasarse los parámetros de una función a otra. Y si fuera, realmente, herencias, tal y como está en las entregas, las flechas deberían de apuntar al revés. Me explico. Si le vamos pasando parámetros de la función "profesorTitular" a profesor, no debería de ser más correcto decir que la función "profesor" hereda de la función "profesorTitular" y no al revés? Al fin y al cabo, es la función "profesorTitular" que le pasa la información a la función "profesor" por mucho que en la función "profesor" se inicializa el valor del parámetro pasado, que ya pasa a ser una variable con valor.

No sé si me he explicaco bien

bermartinv

  • Avanzado
  • ****
  • APR2.COM
  • Mensajes: 298
    • Ver Perfil
Re:CU01150E JavaScript call, Diferencia con apply
« Respuesta #6 en: 21 de Febrero 2016, 21:40 »
REcuerda dimiste, que tu los datos los mandas al objeto profesorTitular o profesorInterino, y estos estaban definidos por unas caracteríticas individuales y por otras características de otros objetos, por lo que tienes que hacer una llamada a estos objetos (call) con los datos que has usado para profesorTitular o profesorInterino.

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Buenas, bermartinv.

Un poquito ocupado estaba, por eso contesto tan tarde. Sí, me acordaré, siempre tengo que pasar las variables de una función a la otra con la sentencia "call". :)

Un saludo

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".