function Student(name, age, prof) { this.name = name; this.age = age; this.prof = prof; this.msg1 = function() { console.log(`my name is ${this.name} my age is ${this.age} and i love ${this.prof}`) } this.msg2 = function() { console.log(`my name is ${this.name}my age is ${this.age} and i love ${this.prof}`) } } //new Student("jack",17,"hacking").msg1() //this works fine //new Student("rose",21,"hacking").msg2() // this too works fine Student.call({}, "jack", 17, "hacking") Student.msg1()El primer argumento de call es el valor de reemplazo de this .
Entonces, está creando un nuevo objeto vacío y pasándolo como this valor a Student . La función Student luego modifica ese objeto. Luego, el objeto, con los valores que se le acaban de agregar, se descarta porque no se hace nada para mantener ninguna referencia a él.
Luego intenta llamar a msg1() en el objeto de la función Student , pero no existe allí porque nunca asigna un valor a la propiedad msg1 de ese objeto.
Ahora podría pasar al mismo Student como este valor.
Student.call(Student, "jack", 17, "hacking")y luego la siguiente línea de su código funcionaría.
Aunque no te recomiendo que lo hagas.
O puede crear un objeto, mantener una referencia a él y luego usarlo.
const jack = {}; Student.call(jack, "jack", 17, "hacking") jack.msg1();Lo cual es menos horrible, pero aún así no es genial.
call es útil cuando necesita tomar prestado un método de un objeto, como cuando tiene un objeto similar a una matriz y desea usar un método de matriz real en él.
Student está diseñado para funcionar como una función constructora. Deberías usarlo como uno.
const jack = new Student("jack",17,"hacking"); jack.msg1();Si desea rediseñarlo para modificar un objeto existente, sería mejor escribirlo como una función normal que esperaba el objeto que desea modificar como argumento.
Entiendo que estoy repitiendo lo que dijo Quentin, pero tengo una respuesta directa.
function Student(name, age, prof) { this.name = name; this.age = age; this.prof = prof; this.msg1 = function() { console.log(`my name is ${this.name} my age is ${this.age} and i love ${this.prof}`) } this.msg2 = function() { console.log(`my name is ${this.name}my age is ${this.age} and i love ${this.prof}`) } } Student.call({}, "jack", 17, "hacking"); Cuando usa la función .call , el primer parámetro se convierte en this dentro de la función. Entonces, cuando dices .call({}, ...) , {} se convierte en this dentro de la función. Lo mismo se completará con las propiedades name, age, prof, msg1, msg2 . Entonces, funcionó como se esperaba.
El problema está en tu comprensión. Pensó que al hacer Student.call({}, ...) se agregarán las propiedades name, age, prof, msg1, msg2 en Student . Como mencioné anteriormente, esas propiedades se completan en el {} que pasó como el primer parámetro.
Entonces, si desea acceder a las propiedades creadas dentro del constructor Student , cree una referencia al primer parámetro y páselo a la función .call . Luego, puede acceder a esas propiedades, a través de la referencia, de la siguiente manera:
const student = {}; Student.call(student, "jack", 17, "hacking"); student.name; // jack student.msg1() // my name is jack my age is 17 and i love hackingPero, como aconsejó Quentin, no use este patrón para crear instancias de objetos. Utilice el constructor en su lugar.