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()
CodePudding user response:
The first argument of call
is the replacement value for this
.
So you are creating a new, empty object and passing it as the this
value to Student
. The Student
function then modifies that object. Then the object, with the values just added to it, is thrown away because you do nothing to keep any references to it.
You then try to call msg1()
on the Student
function object, but it doesn't exist there because you never assign a value to the msg1
property of that object.
Now you could pass Student
itself as the this value.
Student.call(Student, "jack", 17, "hacking")
and then the next line of your code would work.
I don't recommend that you do though.
Or you could create an object, keep a reference to it, and then use that.
const jack = {};
Student.call(jack, "jack", 17, "hacking")
jack.msg1();
Which is less horrible, but still not great.
call
is useful when you need to borrow a method from an object, such as when you have an array-like object and you want to use a real array method on it.
Student
is designed to work as a constructor function. You should use it as one.
const jack = new Student("jack",17,"hacking");
jack.msg1();
If you wanted to redesign it to modify an existing object, then it would be better to write it as a regular function which expected the object you wanted to modify as an argument.
CodePudding user response:
I understand that I am repeating what Quentin said, but, I have a straight forward answer.
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");
When you use .call
function, the first parameter to it becomes this
inside the function. So, when you say .call({}, ...)
, the {}
becomes the this
inside the function. The same will be populated with name, age, prof, msg1, msg2
properties. So, it worked as it is expected to.
The problem is with your understanding. You thought that, doing Student.call({}, ...)
will add the name, age, prof, msg1, msg2
properties in Student
. As I mentioned above, those properties are populated in the {}
that you passed as the first parameter.
So, if you want to access the properties created inside the Student
constructor, then create a reference to the first parameter & pass that to the .call
function. Then, you can access those properties, through the reference, as follows:
const student = {};
Student.call(student, "jack", 17, "hacking");
student.name; // jack
student.msg1() // my name is jack my age is 17 and i love hacking
But, as Quentin advised, do not use this pattern to create object instances. Use the constructor instead.